I have camera across a very weird issue where my batches count significantly increase if I enable GPU instancing: Before applying GPU instancing"

enter image description here After Applying Gpu Instanching: enter image description here

I have a pylon object where i am sharing the material with standar specular shader.

  • \$\begingroup\$ Is it possible these objects were being combined into a static or dynamic batch previously? In particular, could they have been batching with other objects that use the same material but different geometry? \$\endgroup\$
    – DMGregory
    Mar 24 at 16:20
  • \$\begingroup\$ Dynamic Batch is already applied and if i don't use dynamic batch the batch count is around 471 \$\endgroup\$ Mar 24 at 16:20
  • \$\begingroup\$ @DMGregory yeah same material with different gemoerty. \$\endgroup\$ Mar 24 at 16:21
  • 1
    \$\begingroup\$ That answers your question then, no? Different geometry can be combined into one batch with static/dynamic batching, but not with instancing, so some objects that could be combined before now can't be combined when using instancing instead, increasing your total batch count. \$\endgroup\$
    – DMGregory
    Mar 24 at 16:22
  • \$\begingroup\$ Sorry, its quite confusing. You mean in my particular case Gpu instancing is not valid either i need to use dynamic or static batching. Right \$\endgroup\$ Mar 24 at 16:26

There are a few different ways we can combine objects for rendering.

GPU instancing gathers together a buffer of vertices with a buffer of instance transforms, allowing you to draw many differently positioned/rotated/scaled copies of the same object in a single draw call, as long as they all use the same material. This also saves some VRAM/bandwidth, since you're sending the vertices just once, rather than again and again for each instance.

Static or dynamic batching does something similar, but accomplishes it by baking the transformations for the instances into one big vertex buffer, containing multiple copies of the object(s) in different positions/rotations/scales. Unity can do this either at build time (static batching), or at runtime (dynamic batching). This costs more memory and bandwidth than instancing, but it can combine multiple different source meshes into a single call, as long as they're small and all use the same material.

In this case, it sounds like your scene has a lot of different meshes using the same material. So when using the static/dynamic batching, Unity is able to combine them into mixed batches, containing multiple different source meshes. That lets it send fewer draw calls in total.

When using instancing, Unity can't combine different source meshes into the same batch, so it has to keep them separate, resulting in more batches in this particular scene.

Some things that could tip the scale:

  • If your game is CPU-bound, the CPU-side work required for dynamic batching could be a bottleneck.

  • If your game is tight on video memory, the copying of vertex data required for static and dynamic batching could be a limitation.

  • If you have only a few copies of lots of different objects, instancing them might not give a big savings.

Because of all these different trade-offs here, the engine can't always pick the best option efficiently on the fly. That's why it's so important to profile, as you've been doing. In your case, it looks like not using instancing is slightly better for this scene, so you can use that information to tune the performance of your game.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.