Sponsored By

Featured Blog | This community-written post highlights the best of what the game industry has to offer. Read more like it on the Game Developer Blogs.

Unity 3D: Batching independently moving GameObjects into a single mesh to reduce draw calls.

Using Unity's SkinnedMeshRenderer to batch multiple separate moving GameObjects into a dingle draw call.

Bill Borman, Blogger

September 10, 2015

3 Min Read

I discovered some black magic for batching to reduce draw calls in Unity recently. Think you can't combine and batch objects that move independently? You can.

You probably know that static 3D models - things that never move at all - can be marked as Static and get automatically batched by the graphics engine. Separate meshes, as long as they use the same material with the same shader, can be combined into one draw call, which means less work for the graphics card (although I'm no expert on how this stuff works exactly).

I have a game where you build vehicles out of lots of of smaller parts. All parts on the vehicles use the same material. All the part textures are baked into one big texture atlas image, and data in the vertices of the parts themselves determines whether they're shiny or dull, or damaged, or hot - allowing the whole thing to use the same single shader.

But that's not enough to get batching working on its own. Unity can do a small amount of dynamic batching - batching for objects that aren't Static - but its limit is only a few hundred polygons. One vehicle part has a few hundred already.

One thing I was already doing is taking all the parts on a vehicle that don't move (I mean, the whole vehicle moves, but those parts all move together with it) and combining them into one big combined mesh when players entered a game. Having one combined mesh is the final tipping point to getting everything batched and reducing the draw calls. (When parts get destroyed I zero the appropriate ones out.)

That helped, but I couldn't combine anything that moved on its own, like weapon turrets and spinning fans, and there was still a lot of that.

Here's the trick, and I know there are others out there searching for the same powers I was searching for. Even batching stuff on the Asset Store often does less than this.

You can combine everything, and have the GPU do the transforms directly on the vertices of the parts that move to put them wherever they need to be. Create one model and change the model as you go. You could write a shader to do it, but you don't even have to, because Unity has built-in support for it. Ever used SkinnedMeshRenderer to animate something with bones? The transforms of the separate moving vehicle parts can be the bones! The Unify Wiki even has an example of how to do the conversion!

So now I combine everything, and it's super fast. There is a little bit of overhead in doing the transforms: People with DirectX11 or newer cards, you'll be doing it on the GPU (check your Player settings in the Editor for the checkboxes to enable this and DX11 mode). Those with DX9 or DX10 cards will be doing it on the CPU. But it's a small amount of extra work either way compared to the gains in total performance - at least in my use case.

Read more about:

Featured Blogs

About the Author(s)

Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like