Why is batch broken if materials are the same?

Hi everyone, I have been searching a lot and I can’t find the real answer:

I created simple meshes:

Everything is perfect and all of them are rendered in 1 drawcall ONLY if all of the meshes have the same color (or all white or all green), but as soon as there are more than one variant in scene… everything is drawn in a lot of drawcalls, which makes no sense for me.

  • all of the meshes are using the same material

  • no textures

  • no MaterialPorpertyBlock

  • color is set by vertex color ( sharedMesh.colors) (only set if color is required)

  • same shader for all: Sprites-Default

  • Why is the batching breaking if they actually have the same everything?

  • Why is the batching breaking that many batches… why not just 2?? (one white, one green)

  • even if it would break into several batches because of the color gradients… why it doesnt happens when all of them are green?

I haven’t been able to find the logic here, I already read the documentation about DrawCallBatching and GPU instancing and aI cant find the reason.

Please, can anyone explain this to me?
Thank you in advance

The Frame Debugger window will tell you why they’re not batching on the side of the window you’ve cropped out of your screen grabs. Select on of those draw calls and there will be a bold:

Why this draw call can’t be batched with the previous one

Literally, that’s the text you’ll see, followed by the exact reason why. If you don’t understand the reason, or how to fix it, post the reason it says here.

1 Like

there is no such a message.
And as I go trough each step I can see in the shader properties that all of them have the same settings

7263565--876505--batching.gif

this what is being drawn on each step.

If some meshes uses vertex color and some other meses doesnt,
Then almost every mesh is rendered in an individual drawcall, and this get worst and worst the more elements I add in screen.

  • I have tried using MaterialPropertyBlocks instead of vertex color, but same result

7264045--876610--batching steps.gif

That’s wild that it doesn’t show any reason for not batching. It seems like you’ve found a case they totally missed. I might suggest reporting this as a bug using the Help → Report A Bug menu in the editor.

However I believe the reason they aren’t batching is this:

Specifically the fact that not all of the meshes have vertex color assigned. Try assigning vertex color to all of the meshes, even when you want them to be solid white.

1 Like

I tried in a newer version (this project has set urp unlit shaders) , and the error says:
unity dynamic batching is turned off in the player settings or is disabled temporarily in the current context to avoid z-fighting.

the funny part is that the dynamic batching option does not appears in the place it should be (settings/ player / right under static batching)
so the last option would be “is disabled temporarily in the current context to avoid z-fighting”

Any idea why this could be?

So, the reason I didn’t reply is because the answer is … no, I have no idea why. I know dynamic batching gets disabled for some things like the shadow caster passes, but I don’t full understand why, and I don’t know why it would only sometimes disable it for what you’re doing here. My expectation is if all objects have the same set of vertex data (ie: they all have the vertex color added) then they can be batched. It doesn’t make any sense that they’d only batch when they’re all using the red to green vertex coloring, unless that code is also adding other vertex properties as well.

1 Like

@yaaashua
To get the dynamic batching option with URP check the settings. In the Project → Assets → Settings.

Then select one of the URP packages High Medium or Low and the dynamic batching check is there

7317370--887689--dynamic 2.png

I am on Unity 2020.3 because all versions before it has the URP Stats window broken regarding batching (It is not updating and also showing negative values in saved by batching)

But still I am struggling to understand what is wrong because it seems the batching does not work. A simple test scene with cubes marked as static and some moving cubes. Both groups sharing their own material and saved by batching is still 0.

And when I check the Frame Debugger the draw calls are same as the quantity of these simple cube primitives.

“SRP: First call from ScriptableRenderLoopJob.” The reason for not batching, but after googling I can not find anything.

This rabbit hole is driving me crazy

1 Like

After further investigating I hope these links help anyone who is in a similar situation. The SRP batches by the shader, so draw calls might be high but it can deliver faster performance because the shader data is stored on GPU instead of constant forwarding of shader data from CPU to GPU.

For anyone else that comes across this, I can confirm that it only dynamically batches meshes with matching vertex attribute channels.

In my case, some meshes were missing a color or tangent channel, where others added a UV1 and/or UV2 channel. This is causing a bit of a headache for us as we’ll now have to break out sub meshes into dedicated meshes based on attribute channel usage, but needs must.

I wish the Frame Debugger would say this instead of “unknown reason”.

As an explanation as to why they don’t batch, I’m guessing it has to do with the 900 vertex attribute limit. If it’s creating a dynamic mesh with say 5 vertex attribute channels, and it suddenly has to batch a mesh with 7, it would have to retroactively apply the missing 2 channels to the whole dynamic mesh, which could push it over the 900 limit. It couldn’t really work backwards to undo previous meshes, or micromanage different possibilities, so it simply starts the process of a new dynamic mesh. Depending on scene rendering order, what would be an expected 1 draw call batch could break down into several. The solution is to ensure all meshes using a specific material has the identical vertex attribute channels.

Are you sure about no MaterialPropertyBlock? Bc its common reason for Unknow reason in SRP batch break and this Property block can be applyed by Animator automatically regardless of current state.