Best way to display large number of objects

I have a use case in which I need to display a large number (5K-40K) of objects and animate a portion of them at at least 15 fps. I’d like to present a super general case and get any feedback from the jMonkey community. Here’s what I’m trying to do:

I have a world with only 3 types of objects (blender models), but for this argument’s sake we’ll say I have a cube, sphere, and a cylinder. I want to be able to display a large number of these objects in the scene simultaneously and animate them via Cinematics. The objects are uniform and solid in color. I need to be able to change the color via CinematicEvents. The cylinders never move in the scene so I’ve static batched them to take care of that optimization.

My question is really focused on the moveable objects. I want to use a BatchNode for all of the cubes and another batch node for the spheres. Let’s assume I have 256 different colors that I want to use for each object. Am I correct that I can create a texture atlas that’s 16x16, with each pixel corresponding to a specific color and use U,V coords to change color of a specific mesh inside the batch node?

My approach is to create the texture atlas and create 1 material, apply the material to every object in the scene, batch the nodes of similar type (Cube, Sphere), and change color of an individual object by setting it’s tex coords based on the new color requested by the user.

Are there any optimizations that I’m missing here? Is TextureAtlas + BatchNode the way to go? Once a geometry is batched will it still be animatable? If you have any other suggestions in terms of direction I would very much appreciate it. Thanks!

Maybee this helps?

1 Like

If you just want solid color, it may be easier to update the color buffer directly and use vertex color.
This way you don’t have to make a special shader and it can work out of the box with the unshaded material.
Also since you wanted to update the texture coordinates, you’d already have a buffer update operation.
Color buffer use more memory than the tex coord buffer but IMO it’s ok.

Though you will have to do that in the batched geom and not on each separated geoms if you want it to be efficient. Else you’ll have to rebatch each time you change a color, which is a no go IMO.

Also…if your objects are identical, you could consider using instancing. Instancing can draw N times the same object in one draw call. It has to be the same geom, with the same mash and the same material.
Then you could change the color according to the geom id in the shader. Though you have to use the latest repo for this, so it not completely a good idea.

If he’s already using trunk (for instancing support) then he can actually have buffers that aren’t instance-shared. Just like the transform buffer. I think you have to manage your instances yourself, though. I don’t think any of the more automatic instancing wrappers provide it… but the low level code supports it.

So, for example, your postion, etc. buffers could be reused for each instance but you can have a color buffer where the data for each instance is unique. If it does have to be self-managed, as long as you create the transform buffer the same way JME does then you should even be able to reuse JME’s shaders.

Edit: that being said, depending on use-case… using the instance ID may still be better.

Using a vertex buffer for color (with the instanced flag enabled) would work, but requires manual management of the instances. Another option is by using InstancedNode, you could have a unique material for each of the 256 colors, and it would automatically instance any models, that have the same color and mesh.

Thank you for all of the replies (and options). I’m using 3.0.10 at the moment, but I’m downloading the master now and will see if I can get instancing going. It sounds promising. I will follow up after I’ve tried it out.

@Momoko_Fan - as far as InstancedNode is concerned, say I have a j3o model. If I instantiate 1K identical models with the same color, but with different locations in space (and moving independently of one another over time), are you saying that since they all have the same mesh (loaded from same .j3o) that they will be instanced automatically?

1 Like

@exit0: yes, that is correct

1 Like