Batching HOWTO

Both dynamic and static batching seem to not be documented at all, or if so not under these terms. It doesn’t even appear in the screenshots on, e.g. Unity - Manual: Player

Could we please get a HOWTO, Tutorial, or some documentation on how these are supposed to work and what we need to do to get them running? At this time, the process is a lot too much trial-and-error for me. I’ve gathered some parts (e.g. having to set the “static” property), but am lacking almost all details (e.g. is an instantiated object going to be included in dynamic batching or only objects that are part of the scene when it starts up?).

All you need to do is having models that use the same material and that arent animated. this will make them batch dynamically if they are not marked static or being batched statically if they are marked static and you are on pro

The short version: to be able to batch something you need to have the same material. Static batching works with static objects only - doing arcane preprocessing when building the scene. Dynamic batching works with anything that end up drawn - so yes it will work with instantiated objects. There are some caveats though: multi-pass shaders won’t be batched (look out for different lighting setup - it can be the source), objects with different scales won’t be batched, there is a limit on vertices number to be able to batch, and no batching for skinned meshes for now.
Hope i didn’t forget anything 8)
EDIT: dreamora managed to answer while i was typing, so consider this long version :wink:

I thought so, but it’s not happening.

I’m instantiating the same object a couple times in a loop, and there is no batching. Since it’s the same object, I’m pretty sure all dimensions, materials, etc. are identical. If I rewrite the same script as an editor script and set the prefab to static, then I do get static batching.

That’s why I’d like some documentation, so I can check if everything is set up the way Unity expects it.

if you test it in the editor you can easily verify that it does not clone the material. just select it on the model, if it leads to the same thing its fine, if it doesn’t you know that you will need to handle it differently.

there should be some manual page on batching, as laready iphone 1.7 had one and the new stuff isn’t different from it. its basically just “must be the very same material instance and have less than 300 vertices and is not animated → will batch dynamic” (unsure if the 300 still holds but there is a restriction on the amount of vertices if you want to use dynamic batching)

Ok, then what am I doing wrong?

Here is the script:

var MyCube:GameObject;
var Size:Vector3 = Vector3(10,10,10);


function Start() {
	for (var x=-Size.x; x<Size.x; x++) for (var y=-Size.y; y<Size.y; y++) for (var z=-Size.z; z<Size.z; z++) {
		Instantiate(MyCube, Vector3(x,y,z), Quaternion.identity);
	}
}

The “MyCube” game object is a simple cube as created by GameObject->Create->Cube

No dynamic batching happening as far as I can see.

Works for me in Editor (2 draw calls for all these cubes - in deffered mode - +1draw call for screen resolve)
EDIT: 1 draw call on device

Strange. About 4000 draw calls for me, deferred mode. (with bump-mapped material, but it’s not the material, a simple cube with default material also causes over 2000 draw calls)

file the bug report WITH repro scene and drop me the case number

Ok, done. Case 377140.

By default Editor is in deferred mode. Most of the shaders are considered multi-pass for that path and as i said before won’t work with dynamic batching. If you switch it to Forward/Vertex-Lit you will see that everything is correctly batched. We will look into possibility to batch multi-pass drawing, but i can’t promise it (there are too many things that can go wrong)

ok, that’s where documentation would be really nice. Like a list of shaders that do work, for example.

Also, I still get 4000 draw calls in forward rendering mode. No batching is happening.

Update: I do get batching in vertex-lit.

Are you using dynamic shadows?

Happens both with and without.

I have a spotlight and a (fill-light) point light in the scene.

What I’d really like to do is understand dynamic batching better. Then I could go and check for myself. What are the conditions for dynamic batching to occur? What disables it? What may or may not work?

I posted some info in first reply. Also you need to put your priorities straight - if you target mobile platforms - you should look into simplest shaders possible - meaning batching will work just fine. If you target desktops - then DrawCalls for dynamic geometry is far less the issue.

1 Like

was so much easier with the iphone cause you didn’t have more than vertex lights, meshes, fixed function materials.
pixel lights make it more complex, programmable pipeline makes it more complex and multipass stuff makes it hell.

I’m rather confident that the list of stuff that it disables is longer than the list that shows you when it works because its commonly rather trivial: receives shadow → won’t batch, multipass → won’t batch, 2+ affecting pixel lights + related shaders → will commonly not batch (as they are often multipass too to scale to infinite light sources)

on the desktop though its also only half as important … cause if you overdo the drawcalls there that badly that it chokes without batching then it might not needfully just be bottlenecked due to the DrawCalls (unlike iphones where the only other reasonable bottleneck to hit is the fillrate beside the drawcalls normally).
The easiest way to optimize on the desktop (or OGL ES 2), and also the one that impacts performance best, is making anything thats not dynamic static (as static batching is much more powerfull) as well as using Occlusion Culling.

Yes, you two, I know both of that, I’ve been doing Unity stuff for a few years now. :slight_smile:

This current project is mostly an experiment in dynamic levels. That’s why dynamic batching would’ve been perfect for my needs, because the level is created by script and can be changed by the user, a bit like minecraft (though it’s a different gameplay). That’s also why occlusion culling isn’t an option.

I’ll probably have to do the batching myself, using CombineChildren or something like it. I was just hoping that the built-in dynamic batching would work for me.

I second this, it needs to be properly documented.
I just spent half the day trying to get dynamic batching to work, and now I read this thread and found out it won’t work for me in a million years.

If i have keyframed mesh animations (just transforms like a car with no deformation) will it be dynamically batched?

No, skinned mesh renderers don’t batch