January 12 2023

Static Batching in Unity Like You Never Saw


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.

What Unity Tells You (Or Not) About Static Batching

Think about static batching. Unity tells you to:

  • Enable the static flag on static geometry
  • Turn on static batching in the project settings
  • Do some texture atlasing to share materials and allow for static batching to work.
  • Be careful with memory!1!!

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: Basics First

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.

Static Batching: Advanced Second

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.

And Now?

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.

Your Options

From here you have three options:

  1. Do nothing (ignorance is a happy place, but at least join my performance newsletter)
  2. Learn static batching from the ground up: spend a few days by yourself or spend a couple of hours in the static batching module of the Performance Taskforce.
  3. Apply for my (expensive) Unity Consulting to get your game done well & quickly. No hassles, just deliverables.

Ruben (TheGameDev.Guru)

The Gamedev Guru Logo

Performance Labs SL
Paseo de la Castellana 194, Ground Floor B
28046 Madrid, Spain

This website is not sponsored by or affiliated with Facebook, Unity Technologies, Gamedev.net or Gamasutra.

The content you find here is based on my own opinions. Use this information at your own risk.
Some icons provided by Icons8