Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Draw Calls vs Batches optimization? [Unity 5]

Discussion in 'General Graphics' started by Lex-DRL, Apr 14, 2015.

  1. Lex-DRL

    Lex-DRL

    Joined:
    Oct 10, 2011
    Posts:
    139
    After U5 was released, the new stats window no longer displays draw calls. Instead, it displays some "batches".
    upload_2015-4-14_14-33-54.png

    Also, looks like documentation about draw calls and batching has been updated and now it says (in the 1st paragraph):
    So, they say I need to optimize batches instead of draw calls... Hm...

    Then could anyone make it clear what exactly batch is? And how exactly it differs from draw call?

    All this time I thought, that batch = draw call. When several meshes are batched it means they're combined together and sent to a GPU (draw-call'ed) as a single mesh with single shader and a single set of parameters (including textures).

    So how do I need to "reduce number of batches, not draw calls"?
    What exactly do I need to do? Apply less batching? Whaaat? o_O

    I googled this topic but all the answers I found so far only prove my point. When people speak about draw calls, batching and optimization, they usially mean "you need to batch as many meshes as possible to a single draw call".

    Am I missing something? Could anyone point me to the right direction?

    P.S.: to Unity Technologies: you definitely need to explain the difference between "batch" and "draw call" terms much clearer in docs. Or, I should say, at least try to explain it at all.
    So far you gave no definition to what the "batch" is, only to the process of batching.
    And at the same time you tell people to optimize these abstract "batches".
     
    Last edited: Apr 14, 2015
  2. colin299

    colin299

    Joined:
    Sep 2, 2013
    Posts:
    181
    From my understanding,
    1 drawcall = CPU tell GPU to actually "draw" something using GPU's current render state.
    1 batch = "change render state" needed( i would say the expensivepart is here, but not draw call itself)

    The image below shows 4 drawcall & (1+3) batches.


    Then, this image below shows also 4 drawcalls , but (1+1) batches.


    1 White box = 1 drawcall
    1 red box = 1 batch


    -----------------------------------------------------
    What unity's "dynamic batching" / "static batching" do is combine the mesh in CPU before GPU start rendering, it will reduce # of drawcall, but NOT # of batches.




    The only way to reduce batches, is to reduce the number of material / # of pass in shaders.

    Please correct me if I am wrong, I wish to understand drawcall/batch relation to performance also.

    REF: http://simonschreibt.de/gat/renderhell/#update11-1
     
    Last edited: Apr 22, 2015
    minte131, tinyant, RakNet and 9 others like this.
  3. Lex-DRL

    Lex-DRL

    Joined:
    Oct 10, 2011
    Posts:
    139
  4. jitwtttl

    jitwtttl

    Joined:
    Aug 29, 2014
    Posts:
    8
    You can see the meaning of batching in this nVidia's reference page 2. Batch Batch Batch
    In the ref, he says batch is

    Every DrawIndexedPrimitive() is a batch
    – Submits n number of triangles to GPU
    – Same render state applies to all tris in batch
    – SetState calls prior to Draw are part of batch


    In fact, DrawIndexedPrimitive() is draw call, (glDrawElements in OpenGL) not batch. But the ref says it is batch.

    And in Unity, You'll notice that Batches Count and Draw Calls(in Profiler) are always the same.
    Theoretically, they are different concept. But, Practically they always happened at the same time.

    And I can not find the situation that Batch Count and Draw Call Count is different.
    in the scene, there are Multi-Sub Object, Multi-Pass Shader objects. But they are always the same.

    I think Unity just want to emphasize batching, not draw call.
     
  5. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    SetPass is probably your state change and draw calls/batches can pretty much be treated with the same thinking. But as always, reduce everything. Reduce draw calls (batches) and reduce set passes :)
     
  6. Zicandar

    Zicandar

    Joined:
    Feb 10, 2014
    Posts:
    388
    I guess they could be different in the case that underlying API has an ability to be sent multiple draw calls from a single command. (I'm thinking instancing, but not sure if that would apply here?)
    Or the opposite, that 1 draw call could actually result in more then 1 batch having to be done by unity or the underlying API.
    Not sure I agree with unity's decision to rename it, but in general I simply treat them the same.
     
  7. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    I am still curious to learn how to do any of this... Here is my case:

    1. According to the frame debugger I have 40 draw calls.
    - 1 for Opaque geometry (camera background)
    - and 39 Unity UI transparent calls
    2. According to the stats I have 42 batches and
    3. 33 SetPass calls
    4. According to Profiler I have 32 SetPass Calls and 41 Draw Calls

    Stepping through the Frame Debugger I notice that I have 4 render passes for graphics that are in the same atlas but they are not drawn as one pass... heck they are not even drawn in sequence. I have stuff from one atlas drawing in 2 passes, then something completely different from another atlas then skip back to the first one, then two more passes from 2 more atlases before skipping back to the first one...

    1 atlas, 1 parent GameObject, 1 canvas, 1 sorting layer, 4 render passes to draw the 3 health bars. Ironically enough, the first health bar loads with background, hidden bar and health bar that goes over it but to element icon. The next pass draws the backgrounds of the other two power bars, the next one draws only the health bars and the next one draws the elements... All from the same atlas. why does it take Unity 4 render passes to draw something from the same atlas to the screen?

    So I ask again... If even graphics from the same atlas draws in 4 draw calls and a 3D object with one material takes one render pass for every single individual mesh that uses that material then how do I get my draw calls down?

    totally not sure if I should believe the 42 batches, the 40 render passes, the 32 WetPass calls, or the 41 Draw calls...
     
  8. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    Oops. Just noticed the date on this thread as I hit the post button. Sorry for necro posting but this is my exact question and it seems to not have had a reply in the past 11 months... Can someone clue me in with the past 11 months of experience? Please? :)
     
  9. Zicandar

    Zicandar

    Joined:
    Feb 10, 2014
    Posts:
    388
    This is simply a guess, but regarding your example:
    I think that when your looking at the frame debugger it's skipping at Least one draw call, the one that copies it to the screen. So that being 1 lower does make sense.
    However why the profiler and stats would not be the same is weirder, but it could likely be for a similar reason and/or the drawing of the stats themselves?

    As for why Unity isn't bacthing things from the same atlas the way you want it to, generally the reason would be that it's not sure if they might overlap or not, and is thereby forced to draw them in the z order necessary if they were transparent.
    Generally transparent stuff is near impossible to batch and/or not worth batching. Some UI's do batch optimizations, however the calculations of overlap ect can easily take a bit of time, and would need to be re-done as soon as something changes position, size, rotation ect.

    p.s. See if the exact difference stays the same no matter how many/few things you have.
     
  10. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    I actually did a few tests and had some interesting observations:

    4 Images not overlapping = 1 draw call
    4 images where all 4 overlap each other = 1 draw call

    I have a very complex prefab with loads of Images that are enabled/disabled at any given time, some with Animators on them and in one instance one is from another atlas and when the game is running is always hidden until needed but when needed it is moved to a separate parent object that houses only the instances of that Image until it is to be "destroyed". At that point it is simply disabled and returned to the prefab in question.

    Now here is the interesting bit... That prefab takes up 3 draw calls. I duplicate it and I still get 3 draw calls. Then I move it so it doesn't cover the other one exactly and now I have 6 draw calls. I move it up further so it doesn't overlap the other one at all and suddenly it goes back down to 3 again.

    It seems that overlapping Image components are only an issue when they are partially overlapping. Strange. Strange in the sense that the offending Image is not duplicated but all draw calls from the entire prefab hierarchy. Though that kinda actually makes sense....

    So here is the question... I have a Health bar background as an Image. Then I have a yellow health bar on top of it.On top of the yellow health bar I have a red one. So when you take damage the red one shows your actual HP while the yellow one gradually updates to catch up. I have three of these health bars and then I have a separate image unrelated to the health bars and they are all in the same atlas and they all have transparency. None of them are scaled.

    Draw call 1 draws this unrelated graphic as well as the one health bar complete with all it's overlapping parts.
    Draw call 2 draws the other two health bar's but only draws the background
    Draw call 3 draws the missing health bars themselves

    So my original question remains... one atlas, one prefab, 3 instances + 1 unrelated graphic. Why does the one instance draw completely, together with the unrelated image, while the other two instances of the same prefab is drawn in 2 additional passes. Notice that I am saying additional passes because it should have been drawn together with the first instance and the unrelated graphic from the same atlas. Why then are the other instances drawn separately and why does the first one contain the background AND the two overlapping graphics while the other instances draw the background and the overlapping graphics in 2 separate passes?

    It is still a mystery but pointing me in the direction of overlapping graphics, thanks for that at least. :)
     
  11. Lyje

    Lyje

    Joined:
    Mar 24, 2013
    Posts:
    169
    Educated guess as to the reason for overlaps increasing the count - shaders without alpha blending can be drawn in any order thanks to z-buffering. Alpha blended shaders however require that objects be drawn in the right order so that objects at the front can overlay the pixels of objects behind them. Therefore, Unity won't batch alpha-blended objects which overlap, as their draw order must be preserved (as opposed to combining them and drawing them at the same time).
     
    fffMalzbier likes this.
  12. Lex-DRL

    Lex-DRL

    Joined:
    Oct 10, 2011
    Posts:
    139
    They can, yes. But they should be drawn front-to-back. This way, any opaque pixel covered by any other opaque geometry won't be re-calculated.
     
  13. Lyje

    Lyje

    Joined:
    Mar 24, 2013
    Posts:
    169
    Sure. My point is just that dynamic batching is far easier for opaque materials (and alpha tested, since there's no blending involved) than for alpha blended. You might get overdraw, (and generally this is cheaper than increased setpass calls), but it'll still work - unlike blending.
     
  14. 3dshay

    3dshay

    Joined:
    Feb 27, 2009
    Posts:
    200
    Hello all, Thanks for such a good informative thread, I personally never worked with unity other than just importing objects to see if the normal are flipped or not, my question is basically how to reduce the batches? is it something to do with actual objects or the textures?

    I am not sure about this explanation :

    ''batches with dynamic batching enabled is 589, it's still a bit to hight, it would be good if you could put props textures to atlases.''

    Any help would be appreciated.

    Thanks.
     
    evolutionindie likes this.
  15. Niter88

    Niter88

    Joined:
    Jul 24, 2019
    Posts:
    112
    First, sorry for replying years later.
    That said, the community's knowledge about this topic has greatly increased since the changes made to Unity.

    Most of the answers are scattered around the forums, I will try to be as concise as I can. And I will provide the mos important links I found on this topic.

    Before I explain this I have to say that the texture (Atlas or not) and material are not the same thing. You can have one Atlas texture for the entire model of a tavern while having different materials for the walls and floor using this same Atlas, each material would be rendered in it's own pass.

    So, MrDude's problem with atlas texture rendering through various passes can be caused by many things. The most common are:

    1- Various objects with the same material and not eligible for Batching static.
    1.2- There will be one batch for each object rendered, plus the material on each one.
    1.3- In case this object was eligible for Batching static, it would have one render for the "grouped" meshes and one for the only material applied to it. If that was the case, turning off one of the objects would not reduce the batch calls because they are all made in one (This affects RAM)

    2- One object with various materials.
    2.1- There will be one batch for this single mesh, and one batch for every material on this object.
    2.2- In case you had duplicates of this objects AND they applied for Batching static, you would see no increasing on the batches, because they would be "grouped" on the same object. So still one for the big mesh and one for each material.

    I will leave here the more relevant links I found on this topic:
    https://docs.unity3d.com/2021.2/Documentation/Manual/optimizing-draw-calls.html
    https://answers.unity.com/questions/589302/combination-of-basic-meshes-or-one-big-mesh.html
    https://forum.unity.com/threads/unity-draw-5-4-introducing-more-draw-calls.426185/
    https://answers.unity.com/questions/9607/what-is-a-reasonable-number-of-draw-calls-relative.html

    If you find any fixes on this comment or topic or want to add something, feel free to do it.
     
    Last edited: Feb 24, 2022