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

Just bumped into this on Gamasutra and OMG why doesn’t Unity provide this information in the tips and hints section on optimisations!

In effect using SkinnedMeshRenderer to combine procedurally ‘moving’ mesh elements (as long as they use the same material) to a single draw call!

The author of the article on Gamasutra uses this optimisation in his game SCRAPS.

And the code to do it on the Wiki → http://wiki.unity3d.com/index.php/MeshMerger

Article Link - Blogs recent news | Game Developer

Isn’t that what Dynamic Batching is for?

This should definitely be mentioned and recommended to all threads / help sections related to making RTS games.

Dynamic Batching is none configurable so can be very quirky depending on the complexity of your meshes and their shading → http://docs.unity3d.com/Manual/DrawCallBatching.html

But there are probably specific reasons why that is the case. You don’t want a batching algorithm that decreases performance instead of increasing it.
But I agree, dynamic batching is probably too generic and is supposed to work in all cases and on all platforms. It would be good to have some control, so you could configure it to your specific needs.

It’s an old and very common technique. I have explained before this is the type of optimization we lean into heavily in our games. It’s not a one size fits all solution though. Depending on the models and type/complexity of the animations, the overhead can be more expensive than the draw call reduction. It’s all about finding the balance depending on the need.

2 Likes

Just noticed this thread. Thanks for the positive feedback on my article. :slight_smile: This discovery really helped me boost performance after I thought I’d reached the limits of what I could batch.

The built-in dynamic batching is super limited, it won’t batch very much together. Certainly you could get to a point with the system I described in that article where all the extra skinning work overshadows the performance gains in draw calls though. Test both your CPU and GPU performance with it on and off - I’m sure there’d be bad cases when it wasn’t better, although my use case is fairly “bad” and it still improved performance. If you have lots of bones (separate moving objects) then performance will be worse, but then that’s also the sort of situation that’ll be giving you draw call performance issues in the first place, so it might still be better!

Remember that there’s the GPU Skinning toggle in the player settings as well, which can switch some of that work to CPU or GPU.

What’s your view on DX12/Vulkan and Instancing (Unity 5.4+)?

Not @Nition , but both are significant steps forward. I’m currently exploring Vulkan/DX12 in my own engine, and it’s nice to not be talking to a black box and instead be able to work together with the driver to get the needed performance. However, it obviously comes at the cost of much greater complexity to implement.

It’s nice to finally get official support for hardware instancing from Unity, it was a pain in the ass in the past. It’s a bit wonky and the workflow is pretty bad right now as it’s obviously in a state of iteration. However, it’s hardware instancing. Not much else to say.

I’m still stuck on 4.7 for my current project! But I saw that hardware instancing was coming and if it works like it should it sounds great. The old trick of turning everything into one mesh with bones should still be useful if your stuff is all different.

I heard something about adding better array support to shaders as well? That could let you do the equivalent mesh-with-bones thing in a shader without using a SkinnedMeshRenderer too (shader does the transforms on the verts to put them in the right place itself).