Increasing BatchNode performance?

Hello everyone,

in my game, you can place and remove buildings. The problem with this is that you start out with circa 2000 (generated trees) and it could theoretically max out at about 90000.
Now, even with only 2000, BatchNode takes about 3 seconds until the game un-freezes. Is there any way to increase the performance of BatchNode?

Thanks in advance for any answers.

Probably not. You are running into fundamental limitations, basically. No matter what, those giant buffers are going to have to go back to the GPU.

It sounds like your trees are pretty sizable, too. Are they each completely different or picked some fixed set?

Ah, sorry.
I think (?) you misunderstood. I meant when I change something, it takes about 3 seconds to un-freeze. While not doing that, BatchNode actually doubles the FPS, but that’s unacceptable if the game freezes every time I change anything.
And the trees are at the moment just two models, altough buildings are in the same node as well.

by change you mean adding or removing an element to the batch node and rebatching?
Because yes, that’s gonna take a lot of time.
BatchNode is meant to have a batched set of geometres and be able to continue to transform them around at a relatively low cost and keeping the exact same api as if the geoms were not batched.
rebatching is ok if you have 100 geoms but 2000 or 90000 is a lot.

If you have trees, you’d better batch then with the geometry batch factory and have a paging system to manage their display state?

For trees where you have lots of the same model, you may also benefit from instancing.

Could you by any chance expand on that?
So what you mean is I take the node that my buildings (and trees) are attached to and send it to GeometryBatchFactory.
But then what?
@pspeed: Any source (wiki etc.) you could point me to?

And no, I didn’t misunderstand… but I think you probably did. :slight_smile:

Whenever you “change something”, the entire batch has to be recreated basically. So that’s another new giant set of buffers that need to be sent to the GPU.

I’d have to do a search… but you can probably do that just as well. Or you can look in the javadoc for the word instanced.

Ah, alright. Sorry.
I’m going to have a look at instancing then, thanks! :slight_smile:

well we’d need more informations, but if you are using JME 3.1 you have the instanceNode.
see here

Basically if you have the same model of tree with the same texture and only the transforms changes that’s a good way to go. You can have thousands of trees drawn with one draw call.Even if you have 2 or 3 different types of trees you can have 1 instanceNode for each type.

Paging means that you’d would spatially split your trees in batches, and pop them in and out depending on the distance of the camera. (frustum culling will take care of the ones outside of the view).

2 Likes

I was wondering about this technique too, would there be a way to add and remove trees from those Instance? And would it be possible to add shadows and other nice looking effect to it?

If this is possible then i might change my whole game logic to get this and add so much grass blade and trees that it will like a real Forest :slight_smile:

Edit: For exemple could we do a InstanceBuffer into an HashMap, which we would use as key the position, then you could add remove as you wish those model

yes and yes.
the adding removing will be a lot faster than with the batch node.
Also blades of grass might not be the best use case. Instancing shines when you instance a fairly complex object.
When you have blade which are basically 2 or 3 triangles batching may be better. Though why would you remove and add blades of grass?

Edit : also note that if you have some animations, all the blades in the same instance node will have the same animation in sync.

oh , ok ok then the Trees and Rock will fit better, i need to learn how to do this.
Edit: by animation, do you mean my Shader Base animation will be synch for all the Grass or will their position still be compile into each vertex Shader?

yes, note that the idea is that the instanced geom are drawn in the same draw call, so the shader is called with the exact same attributes, unifroms etc…
Maybe one easy workaround would be to randomize the anim (or offset it) with the instanceID that is sent to the shader.

1 Like

That would do the trick :slight_smile: , but the animation wouldn’t consider the Wind effect unless i know for sure there position, I will have to work with this and see for my self what are the possibility. My goal is to lower the need of Batching my scene, since my map is unlimited and as tile of 64x64, the batching require too much cpu time and may Freeze my game for 0.5sec when loading a new map (Load 3 or 5 at a time normally)

So to make this short, i could probably save cpu time on a scale of 4096*3 or *5 geometry to batch :stuck_out_tongue: and maybe increase my scene view! :slight_smile:

The IsoSurfaceDemo does wind with batching (grass) and with instancing (trees). I had to use custom shaders.