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:
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
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.
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.
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.
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.
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.