Hi guys, I faced an issue with profiling my game. I’m creating a simple mobile game with a lot of objects, each object has about 20 vertices and I have about 600 objects in the scene on my Mac it works fine, but on the phone, the game takes about 20-30ms to draw a frame and it looks freezing.
In the built-in profiler, I can see that these objects take about 4ms for an update, but the update method for these objects is empty, it really strange for me.
Also, I run the game with profile UI enabled and I see that top of slow methods are:
clear screen - up to 10ms (I do it twice per frame)
draw render list - up to 15-20ms
setvertexbufferdata - 10ms
renderbatch - 5ms
renderbatchworld - 5ms
resources:
ModelVertexBuffer - 13217280
DrawCalls - 43
The question is why it takes so much time to draw 600 simple objects, they are in the same collection proxy, the same model, the same material and I do not pass any shader constants per object, only on init I use the same tint for each object. And why I have so much draw calls?
If they are always the same you can pass the tint as a render constant when drawing the predicate tag which should not break batching.
There may be other issues with your game. If you can upload a stripped down sample where you still see the frame time issues that can help diagnose it and enable us to suggest improvements.
One is batching. If the material uses World Space, then we batch all the models into a single vertex buffer. This takes time on the CPU, but saves draw calls, but is costly on lower end devices.
Second issue is that we don’t support instancing. If you instead choose Local Space vertices in the material, each model will produce a separate draw call.
I hope we can work on instancing this year, as we very recently updated our engine to support OpenGLES 3. But we have no ETA for this feature.
Until the instancing is implemented you can try separating your models and scripts, have a single script that manages all instances of your model.
If the model is simple, you can win a few ms by using a custom material and removing unused lines from the shader.
Also it’s interesting if you would get different results with the mesh component instead of the model component. You’d have to try both local space and world space coordinates.
Even doing this on init will break drawcalls. If the tint is consistent you need to set it in your render script as a render constant when drawing the model predicate tag.
You can send your project to @britzl or @Mathias_Westerdahl so they can see the main cause of breaking batching. If you are okay with posting it publicly you can upload as zip here. Or make stripped down version which still has too many drawcalls and post here as zip.
So this is a minimal sample of what I do in real code. You can see that it takes 4ms to update 1000 objects
Found strange issue, now it takes only 3 draw calls, will investigate further.
FPS drops to 45 on my phone