January 12 2023
Reason for this blog post is simple:
Most developers think they know how static batching truly works. But that’s a lie: they don’t.
They just know the basics Unity taught them, while ignoring all the low level details that would otherwise explain why static batching kinda sucks sometimes or doesn’t work at all in common situations.
Think about static batching. Unity tells you to:
And their promise:
→ Performance.
Problem is, static batching doesn’t work well in many cases. And it doesn’t work at all in other cases. But you’ll not really understand whyif you don’t understand its complicated internals. And certainly you won’t know what to do instead.
And not that I am going to explain it all here. For that I have a fully dedicated training module on my Performance Taskforce membership. But at least you’ll get a level of awareness that you didn’t have before.
So let’s dive in.
Static batching promises you to pre-combine static meshes together so that you can potentially emit fewer draw calls. You don’t change the mesh, so you can batch more draw calls. Sounds good because it is (usually) good.
And you do this by marking the Batching Static flag in your target mesh renderers. If you do this and enough mesh renderers share the same material, then you get static batching to work.
That’s it.
More advanced bits now:
First, Static batching does not necessarily reduce draw calls, although most of the times it does. The important bit is that static batching makes the individual draw calls (much) cheaper.
Second, Static batching usually requires using two different types of buffers: vertex buffers and index buffers. The first one ocntains all the per-vertex attributes (local position, uv, normals, etc). And the second buffer contains the indices that define the triangles we want to render.
Third, you can break static batching by messing up with the game object and mesh renderer activation state during Awake. So don’t do that.
Fourth, your memory usage might skyrocket. An example is a forest of 1000 trees. All the trees will become a big chunk of mesh, so memory will be like 1000 * memory_of_one_tree. Sometimes it is just better to use GPU instancing instead.
So it all comes down to understanding the internals of static batching in Unity. Because things will go wrong eventually. And getting accurate training on how each performance optimization works is a solid investment for you. You’ll know what to look for, how to react, and be able to guide your colleagues and project.
When studios contact me for Unity performance optimization consulting, half of the time I diagnose improper usage of static batching. And this harms your game and fanbase because it increases loading times and crash rate unnecessarily.
So be on the look out for this.
From here you have three options:
Ruben (TheGameDev.Guru)