Search Unity

Sorting Order breaks Batching?

Discussion in '2D' started by Marrt, Jun 17, 2015.

  1. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    Short: How does sortingOrder impact Drawcalls on batched Sprites?


    I got a combined Sprite with 3 or more different values for sortingOrder (sortingLayer is set do "Default", all Sprites are in the same Atlas with correct packing Tag). This creates 3 drawcalls If i use the same sortingOrder value, Drawcalls shrink to 1.
     
    ObsoleteOne likes this.
  2. Kuan

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    87
    Sorting layer should not affect batching and I didn't observed the behaviour you described. Which version of Unity you're using? Do you think you can share more detail or the project or better yet, file a bug with the example project you mentioned?
     
  3. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    Unity 5, but i didn't install the latest patch yet.
    I will update Unity and compose a small example project tonight when im home.
     
  4. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    took some tinkering but I reduced my 400MB Build down to the essential Problem:

    run the scene, then enable/disable the parents called
    "CreatesAtLeast2DrawCalls" "Floor1" "Floor2" and look at the drawcalls
    • I get 1 Drawcall for "Floor1", 2 for "Floor2" and 2-4 for "CreatesAtLeast2DrawCalls"
    • "CreatesAtLeast2DrawCalls" is getting its SpriteRenderers and Sprites at runtime through the Script "Test1.cs"

    Attached the project folder
     

    Attached Files:

  5. Pharan

    Pharan

    Joined:
    Oct 28, 2013
    Posts:
    102
    I think when you intersperse two different materials (or material property blocks, as what two SpriteRenderers that use sprites coming from different textures would use), it breaks batching.

    Assuming you only have one sorting layer:
    If you have material A & B in order 0. you get 2 batches.
    if you have material A & B in order 0, then the two materials again in order -1. you get 4 batches.
    but if you only have material A, order 0, 1, -1, -2 and nothing else there, you get 1 batch.

    I think that's how it works.

    Do confirm with tests though. This is just how I remember it working from way back in 4.3, and I didn't go about testing it rigorously.

    Take note that all Renderers obey sorting layers and sorting order. It's just that those fields are hidden in the inspector. (They are public properties in code.)
    Any non-Sprite Renderer (including MeshRenderers) is rendered in the "Default" sorting layer at sorting order 0 by default. That means putting any sprites in the default layer will intersperse with other types of Renderers.
    Whether or not this breaks batching, that's up for testing (or up to Unity Technologies to explain to us).
     
    Last edited: Jun 18, 2015
    theANMATOR2b and Marrt like this.
  6. Kuan

    Kuan

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    87
    @Pharan. Thank you for the detail explanation. It is spot on.

    @Marrt. I checked out your project, the issue is exactly what Pharan explained. Your "floor" sprite and "Tiletemplate" sprite are in different format and thus create 2 different atlas (due to 2 different format) despite they share the same packing tag. You can verify this with the Sprite Packer Window. This made them use different material for rendering. Therefore, if they mixed up in the rendering order, they will cause extra draw calls.

    Of what is going on, Pharan's explanation above is spot on. I will add my bit here.

    Before going into batching/rendering. All renderers will be sort (sorting layer and sorting order played their part here). After the sorting, these renderers will be determine for batching in the sorted order. Renderers of same material will be batch together. But this will break as soon as one renderer in order is not using the same material. Another batch will start and draw call +1.

    More about batching : http://docs.unity3d.com/Manual/DrawCallBatching.html.

    To illustrate, I will borrow Pharan example of A and B material. And introduce 4 sprite renderes. a1 and a2 used material A. b1 and b2 will user material B. Assume the scene only consist of these 4 sprite renderers and nothing else.

    Scenario 1. Those sprites are put into order of a1, a2, b1, b2. This will cause 2 draw calls / 2 batches.
    Scenario 2. Those sprites are put into order of b1, a1, a2, b2. This will cause 3 batches.
    Scenario 3. Those sprites are put into order of a1, b1, a2, b2. This will cause 4 batches.

    As mentioned by Pharan, putting those renderers in default layer might conflict order with other renderers and you will get undesired result.
     
    ObsoleteOne and Marrt like this.
  7. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    Thanks guys! That totally makes sense now.
    Even if you think by the tool<=>Material analogy. If you have to draw lower sortingOrder-Sprites earlier and can only ever draw others on top of them to achieve a sorting order effect, it is obvious that you would have to switch tools between rendering sortingOrders if more than one tools is used


    So to wrap it up in one conclusive statement for anyone who stumbles upon this thread:

    Batching of one Material(or Atlas) between different sortingOrders will break if another Material has to be rendered in between those sortingOrders.
    Beware that different sprite formats will create separate Materials despite their packing tag. Check the Sprite Packer Window to see if your Sprites have been packed together
     
    Last edited: Jun 18, 2015
  8. shivaprasad_unity

    shivaprasad_unity

    Joined:
    Mar 30, 2021
    Posts:
    19
    If any one comes here after 7 Years....
    You can avoid this batch breaking using sorting layers. If sorting group is something you do not need to do the same job.
     
  9. kumawatb003

    kumawatb003

    Joined:
    Apr 26, 2022
    Posts:
    4
    thank you very much for save my time again thank you