Optimizing Cube Rendering- draw calls and batching

I am currently working on a project that involves a lot of cubes- literally. Take a look:

The red tiles and purple tiles both use the same shader. However, they are using different materials, so that certain tiles can have a certain color, specified by our artist (he uses Strumpy). We have a system in place using shared materials to Lerp the colors over time- this is a huge feature in our game.

We are looking for a way to optimize this. In the screenshot- without the purple, there are only 3 draw calls. For every purple block, 2 draw calls are added. This confuses me- if I use materials that use the default diffuse shader, they batch super well.

Why is this, and what can we do better/smarter?

Open to any other suggestions as well! Thanks

You said that a single purple block adds 2 draw calls? Well then you seem have a multipass shader. This can be due to enabling shadow casting on the cube mesh renderer or just the way the shader is designed.

I recommend reading the Draw Call Batching documentation if you haven’t already: Draw Call Batching. It is short and crucial. They include a sort of batching checklist. Emphasis is mine.

  • Batching dynamic objects has certain overhead per vertex, so batching is applied only to meshes containing less than 900 vertex attributes in total.
  • If your shader is using Vertex Position, Normal and single UV, then you can batch up to 300 verts; whereas if your shader is using Vertex Position, Normal, UV0, UV1 and Tangent, then only 180 verts.
  • Please note: attribute count limit might be changed in future
  • Generally, objects should be using the same transform scale.
  • The exception is non-uniform scaled objects; if several objects all have different non-uniform scale then they can still be batched.
  • Using different material instances - even if they are essentially the same - will make objects not batched together.
  • Objects with lightmaps have additional renderer parameter: lightmap index and offset/scale into the lightmap. So generally dynamic lightmapped objects should point to exactly the same lightmap location to be batched.
  • Multi-pass shaders will break batching. Almost all unity shaders supports several lights in forward rendering, effectively doing additional pass for them. The draw calls for “additional per-pixel lights” will not be batched.
  • Objects that receive real-time shadows will not be batched.