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. http://unity3d.com/support/documentation/Components/class-PlayerSettings.html 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 ;-)
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: Code (csharp): 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)
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.
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.
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. 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?
I would like to add to this question on batching. I have lots of dynamically generated meshes, that were dynamically batching (from cca 200 DC to 9 DC) combined into a few meshes via mesh combine and now i have batching from 20 DC to 9 DC, but with a cca 40% performance increase in frametime (in the editor), which is good. Now, for example if I want to switch to static batching instead, and use StaticBatchingUtility.Combine(parent), in the editor I do not actually see a performance difference, (of course in Xcode profiler there is a memory usage increase) but I wonder, how do I know if they are now marked for static batching from the editor, just if I want to check. Shouldn't the [√] Static be checked in the editor during runtime for me after the said operation? Because it's not EDIT: Oh, but when you try to move the statically batched object in the editor, it cannot move, so that way you know... And also the Mesh Filter component shows that it is a combined mesh (root: parent)
in unityPro 3 under Edit>Project Settings> Editor, i have no option to set to deffered.... only "Enable" which looks like versioning control... am i missing something? more about my draw call situation: (maybe someone can point out the problem) 1, I instantiate a cubePrefab 120 times in a loop (similar to the first post of this thread) - seems ok 2, the cubePrefab has a diffuse material with a texture atlas applied to it - is this a safe material type? 3, after instantiation, i set the render.material.SetTextureOffset to one of 8 possible offsets - i think this might be it, cause I've heard this will create a new reference to the material, but if i have 120 cubes, and only 8 possible different offsets, shouldn't my Draw Calls price be maxed at 8? cause after that they'd be identical again with all other cubePrefabs with the same offset? If you'd like any more info, I'll gladly provide it! Any tips, are totally appreciated!!! Thanks in advance!
If you don't own Unity Pro you can't enable deferred. Deferred also would be set in the Player Settings, not the Editor Settings actually
I own unity pro and not seeing it under the Player Settings, im not seeing it under any of the iOS settings, or anywhere actually? how blind am I?
In that case its just a matter of going to the Player Settings and changing the render path for your Windows / OSX / Web Project from Forward to Deferred
K, i just tried all three (forward, deffered, and vertix) all still didn't batch. any thoughts on the .SetTextureOffset issue? if I comment out this code it actually batches... why wouldn't the offset maintain the batch?
Do you set the texture offset explicitly for each object or do you just create eight materials with the right offsets and reuse them? I don't think Unity can detect that the texture offset for two materials is the same and infer that they are essentially identical. If you reuse a set of materials then you shouldn't have this problem.
i have one material, and one texture on one game object called cubePrefab. after i instantiate a cubePrefab, i set the texture offset on the material to one of 8 different predefined values. ( i do this 120 times in a loop) i have this set up because 'currently' i plan on switching the offset to view a different portion of the texture when they collide with an object in scene Hopefully this info is clear, if not let me know! I guess I can tell you that I do not have eight different materials with NON-changing offsets... if i DID set it up this way, could i still change their texture offset later? or would i be in the same position I am now? Thanks again for the attention!
That is what breaks the batching. If you touch the material after instantiation and change any value, you are technically creating a cloned new material
k, I thought it would sort of "cache" the whole texture on the material, and then just show a section, instead of thinking it was something new each time. ... if i animate it (through an animation clip, or by scripts that would edit the scale values) will that break it as well?
Any progress in providing adequate documentation for batching? I don't see anything new. Are there any plans to provide it? Or is it as with everything else in unity - NO useful DOCUMENTATION as usual?
If I move or rotate an object, will it still be batched? if so under what conditions? As for iphone does the 300 vert limitation still hold? Will it batch if I move it? Also if I export an animation under FBX which uses parented meshes to bones, is it still skinned or dynamically batched? I would not be using a skin modifier of any kind, just objects parented to bones.
Models sharing the same material, rendering path set to Vertex Lit, and this is what I get: Adding 18 models with 25 verts each, become 1 drawcall (450 verts total) Adding 2 models with 212 verts each, become 2 drawcalls (424 verts total) How come?
your 212 verts model likely is not 212 verts out of unitys view. The limit for batching is 300 real / unity verts with 1 UV set, position, normal. If you have other data like 2nd uv set or tanget, the limit is further reduced
Its the vert count specified by Unity in the stats window and in the mesh preview window in the inspector. Those are not trustworthy then? Only 1 UV and standard diffuse shader, calculated normals 180 deg, no tangents. 1 directional light, forward rendering path. Update: Crunched the model to half the polycount, created a simple UV unwrap (looks wonky), ended up with 48 verts pr mesh and could add 5 of them and get 1 drawcall, the 6th made it into 2 drawcalls, and the 11th pushed it into 3 drawcalls. So 240 verts pr drawcall. 3 ships with 71 verts become 1 drawcall, while the 4th generates another drawcall. Adding a textured quad (two triangles) x 128, it batches into one drawcall, the 129th quad adds the second drawcall. 4 verts x 128 = 512 verts in one drawcall.
Hmm out of ideas then given it does not use skinned renderers which don't batch at all and if no lights / no shadow casting are present.
if you are using 3.3 - we screwed editor stats window - batched counter is wrong here (sorry guys) Can you try profiler? It shows batched correctly if it is still 0 - bug report and drop me case number
I don't think I have a bug to report, as the profiler says the same. I think we can establish that it is a "fact of life" that Unity does not batch an infinite amount of models into one drawcall (even if they are only 4 verts each). What I am struggling with is to figure out the hard facts about how things are calculated. 2 models with 154 verts become 1 drawcall, while 2 models with 162 verts become 2 drawcalls (see attachment). It can not be that the total has to be below 300, since 154 verts x 2 = 308, and as shown previously with 4 verts x 128 = 512 and still 1 drawcall. What black magic is going on in the background here?
The not "infinite" is correct. The border is at the point where doing the batching costs more than what you gain (it was previously for iphone 1.x mentioned as 4000 verts per batch, for desktop it is likely higher). The 300 is definitely per mesh renderer (not skinned mesh renderer) to batch, not in total though
But practice says otherwise, both in the stats window and the profiler. Should I disregard their output as wrong and/or that my model is fudged? Please give the model a go and see the difference in batching by going from smoothing angle 97 <-> 98 (154 vs 162 verts). Could the 154 verts indication actually be closer to 290-some, and 162 verts just above 300? The obj consists of 84 verts and 84 UVs (so no discontinuous UVs), normals are calculated inside Unity.
As of now, me and Leigh Bamforth who is doing the models, aim for 130-ish verts and polys pr model, and by doing so we manage to get 3 ships into one drawcall (see attachments).
Actually the most annoying issue related to batching which hasn't been covered is the scale dilemma. i've seen loads of Youtube vids on importing FBX files and some of them told you to re-scale in your 3D application, some said in Unity but none of them happen to mention scaled objects won't batch !!! keeping your imports at real life scale is no good because Unity re-scales everything to 0.01. OK, you say what's wrong with that ? well in case you haven't noticed the zoom ( scroll wheel ) seems to zoom at set increments and at this bloody micro scale good luck in trying to get close to your objects. SO.... can't use the default scale because it sux and can't re-scale cause it won't batch. has anybody else fixed this issue ?