Performance issue: fps drops significantly when meshes count over thousand

Hey, team! Recently when I tested some large models with babylonjs, I found that if the model contains thousands of meshes and the vertices count over two or three millions, the fps would significantly drops. And I also test in threejs, and no issue over there.
Here is the model stats in babylonjs and threejs:
babylonjs:

threejs:

Since I doubted that maybe it’s something related to the meshes count or the vertices count. So I make a simple demo here:

Is the pressure on the framework too great with thousands of meshes, or is there some problem that needs to be addressed

And if you move the camera, you would find an interesting phenomenon that the closer the distance to the camera, the lower the fps, also the farther the higher

I am using MacOS 26 M4 and the Edge browser.

It’s not primarily the vertex count that’s the problem here, it’s the mesh count. With every new mesh we add, the number of draw calls increases. Each draw call requires the CPU to tell the GPU what to render for every frame. In this case, the CPU has to do that 4,600 times every single frame. Using instances would be a better approach here.

How to explain why the threejs does not encounter this issue? I tested the same model in babylonjs and therejs but different result.

And also if you see the PG, two thousand spheres causes fps significantly drops and the camera distance affect the fps. I think maybe there are some internal issues when exec the render frame call.

image

this is what is killing you.

I can make a PG with 100000 spheres, you just gotta do it right.

Look into merge mesh operations, instances, and thin instances even the SPS. You have a lot of ways to do large mesh counts.

I know that and also know how to optimize it! Since I try the same model in threejs and babylonjs and I think there are some differences in performance. I tested in three many times, it usually only drops by around 5 frames and sometimes can keep 60 fps, but for babylonjs it seems the fps drops a bit more.

Maybe the PG is not that correct to repro my issues, I am trying to generate a proper model to compare the performance bettwen babylonjs and threejs.

Oh, another tip, the stats using babylonjs scene which is not adapted the divicePixelRatio while the threejs is.

Do you have the model, it sounds like however you are loading it in Three JS is seeing each of the meshes as the same geometry maybe and is auto instancing them for you? I highly doubt you are at 1 draw call per mesh in Three for some reason if its running well.

I think this can explain why, the threejs official editor auto enable the Draco and Ktx2Decoder to optimize the model and threejs also create geometry key to reuse buffers when parsing the mesh primitives.

Not this.
The threejs stats:

Now I don’t know what’s going on. Threejs just performs better.

I will provide a test model later and also the demo to compare.:smiling_face_with_tear:

Did you try the usual suspects? like freezeActiveMeshes etc.. ?

Here is an image showing that the GPU is 100% utilized when zoomed in, but not when zoomed out. This seems to indicate there is just too many pixels to draw when each mesh has to be in a separate draw call. On my 4070Ti Super I have no issues with 2500+ draw calls in VR but the size of the meshes in my frustrum does, indicating the GPU is stretched with how many pixels it can draw.

Thin instances for all the spheres would ofc be way simpler and faster. I doubt this is frustrum culling problems although that adds up. In my example above I did add a freezeWorldMatrix() at least for each of the meshes.