Search Unity

Batching HOWTO

Discussion in 'Editor & General Support' started by Tom163, Oct 5, 2010.

  1. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    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?).
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    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
     
  3. Alexey

    Alexey

    Unity Technologies

    Joined:
    May 10, 2010
    Posts:
    1,624
    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 ;-)
     
  4. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    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.
     
  5. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    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)
     
  6. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    Ok, then what am I doing wrong?

    Here is the script:

    Code (csharp):
    1.  
    2.  
    3. var MyCube:GameObject;
    4. var Size:Vector3 = Vector3(10,10,10);
    5.  
    6.  
    7. function Start() {
    8.     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++) {
    9.         Instantiate(MyCube, Vector3(x,y,z), Quaternion.identity);
    10.     }
    11. }
    12.  
    13.  
    The "MyCube" game object is a simple cube as created by GameObject->Create->Cube

    No dynamic batching happening as far as I can see.
     
  7. Alexey

    Alexey

    Unity Technologies

    Joined:
    May 10, 2010
    Posts:
    1,624
    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
     
    Last edited: Oct 5, 2010
  8. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    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)
     
  9. Alexey

    Alexey

    Unity Technologies

    Joined:
    May 10, 2010
    Posts:
    1,624
    file the bug report WITH repro scene and drop me the case number
     
  10. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    Ok, done. Case 377140.
     
  11. Alexey

    Alexey

    Unity Technologies

    Joined:
    May 10, 2010
    Posts:
    1,624
    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)
     
  12. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    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.
     
    Last edited: Oct 6, 2010
  13. antenna-tree

    antenna-tree

    Joined:
    Oct 30, 2005
    Posts:
    5,324
    Are you using dynamic shadows?
     
  14. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    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?
     
  15. Alexey

    Alexey

    Unity Technologies

    Joined:
    May 10, 2010
    Posts:
    1,624
    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.
     
    jiangdan8564101 likes this.
  16. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    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.
     
  17. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    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.
     
  18. chai

    chai

    Joined:
    Jun 3, 2009
    Posts:
    84
    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.
     
  19. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    If i have keyframed mesh animations (just transforms like a car with no deformation) will it be dynamically batched?
     
  20. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    No, skinned mesh renderers don't batch
     
  21. ANTROPO

    ANTROPO

    Joined:
    May 26, 2010
    Posts:
    51
    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 :D

    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)
     
    Last edited: Jan 9, 2011
  22. speedsimmons

    speedsimmons

    Joined:
    Dec 4, 2010
    Posts:
    20
    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!
     
  23. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    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
     
  24. speedsimmons

    speedsimmons

    Joined:
    Dec 4, 2010
    Posts:
    20
    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?
     
    Last edited: Jan 18, 2011
  25. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    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
     
  26. speedsimmons

    speedsimmons

    Joined:
    Dec 4, 2010
    Posts:
    20
    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?
     
  27. speedsimmons

    speedsimmons

    Joined:
    Dec 4, 2010
    Posts:
    20
  28. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    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.
     
  29. speedsimmons

    speedsimmons

    Joined:
    Dec 4, 2010
    Posts:
    20
    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!
     
  30. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    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
     
  31. speedsimmons

    speedsimmons

    Joined:
    Dec 4, 2010
    Posts:
    20
    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?
     
  32. speedsimmons

    speedsimmons

    Joined:
    Dec 4, 2010
    Posts:
    20
    also, this means any sprite sheet animation will always get it's own draw call, yes?
     
  33. tarragon

    tarragon

    Joined:
    Dec 28, 2010
    Posts:
    38
    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?
     
  34. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    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.
     
  35. MentalFish

    MentalFish

    Joined:
    Nov 2, 2005
    Posts:
    282
    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?
     
  36. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    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
     
  37. MentalFish

    MentalFish

    Joined:
    Nov 2, 2005
    Posts:
    282
    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.
     

    Attached Files:

    Last edited: Apr 13, 2011
  38. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    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.
     
  39. Alexey

    Alexey

    Unity Technologies

    Joined:
    May 10, 2010
    Posts:
    1,624
    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
     
  40. MentalFish

    MentalFish

    Joined:
    Nov 2, 2005
    Posts:
    282
    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? :confused:
     

    Attached Files:

  41. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    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 :)
     
  42. MentalFish

    MentalFish

    Joined:
    Nov 2, 2005
    Posts:
    282
    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.
     

    Attached Files:

  43. MentalFish

    MentalFish

    Joined:
    Nov 2, 2005
    Posts:
    282
    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).
     

    Attached Files:

  44. 80sOGRE

    80sOGRE

    Joined:
    Feb 16, 2013
    Posts:
    24
    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 ?