Understanding Instances & Draw Calls

Hi All,

I’m working with a designer who wants to render 10k(ish) trees in our scene. From looking at various instancing examples, it seems like this should be plausible, but in practice, it’s lagging hard.

PG: https://playground.babylonjs.com/#V902JW#2

I’ve created a playground that places 10k instances of our model. My understanding of instancing is that I should be seeing only a handful of draw calls, not the 1.5k+ I get with this scene (as per screenshot below).

I’ve also noticed, that if I leave the scene for some time, eventually the number of draw calls drops to 101. I can’t see any reasoning behind this, but naturally the FPS/performance is smoother once this kicks in.

Any other techniques/guidance is really welcome here.

Thanks in advance

Have you tried alwaysSelectAsActiveMesh = true on the instances?
My GPU sucks, so my frame-time takes up most of the frame budget, but coming in second is meshes selection

1 Like

if you scroll down you will notice that the amount of draw calls whether you have 10 or 10000 trees is the same. the issue you are experiencing (reduced performance) is due to the mesh-selection process. There are a few ways to optimize this process, one of them to set the meshes to always be selected (mesh.alwaysSelectAsActiveMesh).

Hello,
did you see this video by @deltakosh?

At 7:00 he shows that there is only one draw call. Hope it helps!

R.

EDIT: And there is another one where he placed a lot of trees on the scene using sprites, but I just can’t recall which one is it :speak_no_evil:

1 Like

Have added that in: https://playground.babylonjs.com/#V902JW#3

It’s dropped from 9.5ms to 7.5ms for me, but still pretty heav lagging.

Hello,

Did you try with thin instances ?

I make a forest with this technic lately and framerate is quite good

Hmm. Setting scene.freezeActiveMeshes() after instantiating the trees seems to help.
Perhaps there’s a bug preventing instances from shortcutting the culling process?

With spheres it seems to work. Each gltf mesh with a different material is converted into primitives. Check the Inspector. So I believe that one mesh/one material x instances = 1 draw call. Maybe thats the reason. Maybe you could try to populate the scene with two spheres with different materials and check whether id doubles the draw calls.

Also check this if your are into instancing :vulcan_salute:

R.

Interesting - it’s all a single/common gltf & material though, so not sure I understand why this would be so high in the first place?

Has anyone got insight into why this might be too please? Draw calls considerably higher at first, then settle after a while.

This is weird I agree.

Digging into it now

2 Likes

Ok problem solved :slight_smile:
It was acutally a bad design that I implemented in the SceneExplorer. Every time a new mesh was created I recreated the entire scene explorer. That was forcing the CPU to spend 100% of its time in react :smiley:

The next nightly will come with a fix so you should not see crazy (and wrong) numbers for draw calls anymore

Furthermore, I slightly updated the initial PG to remove picking for the trees and the ground to avoid perf issues when moving the mouse:

Tree Instancing from GLTF | Babylon.js Playground (babylonjs.com)

4 Likes

Thank you @Deltakosh!

Interesting observation, the draw calls were all in fact coming from the ground: https://playground.babylonjs.com/#V902JW#10

I was confused as to why that material freeze would free up so much, but turns out that line hid the ground in your PG, therefore clearing the draw calls:

1 Like

So finally we know the reason :slight_smile: