Unity GPU Instancing

Unity 5.6 is available now and has some great performance improvements you can take advantage of.  Today I’m starting a new series covering some of these enhancements and the performance benefits you can gain.  These simple tips will keep your FPS high and your players happy.  This post will cover the new Unity GPU Instancing system.

Introducing Unity GPU Instancing

GPU instancing allows your to render a large number of the same mesh/material in just a few draw calls.

While it was possible to get instancing working partially in 5.5, full support is now available in 5.6.

Now, the standard shaders all support GPU instancing with the check of a box.

How do I use it?

Enabling Instancing is actually very simple in most cases.  If you’re using the Standard shader, look to the bottom and check the “Enable Instancing” box.

That’s all you need to do!

If you want instancing for other shaders, you can check out more details on how to set that up here: https://docs.unity3d.com/Manual/GPUInstancing.html

 

When should I use it?

It’s important to note that GPU instancing doesn’t work on skinned mesh renderers, so you can’t just drop it on any character and see the gains.

Where you’ll see the most improvement is with a large number of objects which share a mesh but have some variety in scale.

For my testing, I setup an asteroid field with 1000 asteroids from one of the free space packs on the asset store.

I generated them with random locations and scales, then compared the draw data.

Here’s the script I used to generate the asteroids:

The Results

Instancing Off

Instancing On

That’s right, the draw calls drop from 4165 to 11!  It’s a huge difference.

What about dynamic batching?

You may be wondering how this is different from dynamic batching.

There are 2 things that really stand out to me.

#1. Dynamic batching requires the objects to be the same scale.  In many cases that won’t matter, but for things like asteroids, trees, or other objects where you want scale variety, instancing comes to the rescue.

#2. GPU instancing is done on the GPU while dynamic batching is on the CPU.  Moving this load over to the GPU frees up CPU time and makes for more efficient use of the system overall.

Conclusion

Instancing is here, it’s great, and you should definitely start checking that box whenever you’re gonna have many instances of your mesh in the scene.  It’s an easy to use optimization and may be one of my favorite Unity 5.6 changes.

  • Alex Coulombe

    How does GPU Instancing compare to Static Batching? I have a thousand static objects and it looks like static batching is still more efficient. Does that sound right?

    • JW

      Yea static batching will be faster for your non-moving stuff, and dynamic batching can handle most of your moving objects too.

      Instancing just takes over for some of the static batching, and moves the load off the CPU, while also covering some cases that dynamic batching can’t do.

      Definitely keep your static batched stuff the way it is, and only look to switch dynamic things that you have a large # of (and have a decent # of verts)

    • Static batching is definitely going to be faster. Instancing is useful for the dynamic objects you have moving around, where static batching won’t work.

  • Matt Radford

    cool, but whats the MS to render?

    • JW

      I did another quick test of 10,000 asteroids and saw a drop from 30ms to 15ms in the render call.

      The actual savings will of course depend on a variety of things (what meshes you’re batching, how many there are, etc), but given how easy it is to enable, I’d definitely recommend flipping it on for things you think may be useful and doing a quick test.

      That simple script in the post could be used to spawn a large # of your own meshes and get an idea how much it’ll save you.