I’m testing out babylon for part of a mobile game, and at what would probably be about the maximum grid size, I’m only getting like ~10fps on my phone.
Using mesh.freezeWorldMatrix() improved the framerate quite a bit (from slideshow to ~10fps), and using scene.freezeActiveMeshes(); gives a significant boost, but is very undesireable, and even with it the scene eats through battery. Turning shadows off gives a small boost as well, but still not quite that “big jump” that’s needed for it to be reasonable.
It seems to be almost entirely CPU bound, which is confusing to me. What is going on here that is hogging so much CPU time?
What sort of suggestions do you have for better optimizing the scene? The gird itself is “dynamic” in the sense that the the tiles can be added whenever, starting with just a few, so it’s not a singular static mesh.
UPDATE:
Lets summarize the perf improvements thus far, starting with a scene with no performance help.
My concern is that this is essentially an empty scene for my use case, there will be scenery, building, moving objects, roads…etc all added that will bring the complexity up. It’s CPU bound, which means the game logic will have to fight for CPU time, potentially degrading it to the point of unsuitability on mid-low end mobile devices. And even on higher end devices, the power usage on this scene with only hexagons is through the roof.
My questions:
What eats so much CPU time?
Why does useRightHandedSystem fix drawcalls and nearly double the FPS?
How could I better setup the scene to be more performant in the first place?
My new MacBook has no problem running at 60 FPS with avg GPU frame time of only 0.95 ms when using clone() or instantiateModelsToScene() on that PG, but using createInstance() I drop to 18 FPS with avg GPU frame time at a whopping 55 ms.
It’s definitely an improvement, but it still seems terribly unperformant, on the pixel for example it eats battery till it thermal throttles and the FPS drops. Something is eating up all the CPU time, any ideas at what?
My GPU time is always < 1ms, but on each device a CPU thread is completely maxed out.
The issue with instances is only on the latest verson of BJS thou. Running it on version 4.2 the FPS is back up to 60 FPS with GPU frame time at only 3 ms.
Switch to the latest version and the FPS is back down to 18 with GPU frame time back up to 55 ms.
That one doesn’t use instances thou, it’s creating a new mesh each time? It’s the one with instances that’s killing perf on latest BJS version on my Mac.
Update, before I was testing on Chrome where the FPS dropped down to 18 FPS with instances, but I just tried it on FireFox and it’s all the way down to 7 FPS and almost completely unresponsive…
I can’t understand which changes in the instance code would raise the GPU time so much… That would mean we are drawing hundreds of times the same thing to account for the change from 1ms to 55ms…
What are the number of draw calls you are seeing for the PG? A Spector snapshot would help a lot, but if you are using a laptop it won’t work…
[EDIT] Also, could you test using WebGL1 instead of WebGL2?
engine.getCaps().instancedArrays returns true. Yep it works on version 4.2 using WebGL2.
Also I guess the inspector is misreporting the number of draw calls, it should report much lower number using instances right, just one draw call for all of them?
No, because you are loading a glb which has right handed data. You will need to set scene.useRightHandedSystem = true; so that all instances are drawn with a single draw call.