Search Unity

Difference between AlphaTest and Transparent RenderQueue?

Discussion in 'Shaders' started by BrightBit, Mar 1, 2017.

  1. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    265
    I am using a depth mask path on one of my transparent materials to avoid order related artifacts. The shader works as expected when I select the AlphaTest RenderQueue but it doesn't work at all when using the Transparent RenderQueue. Do you know why? What happens to materials in the Transparent RenderQueue?

    Here you can see what I mean:



    Here's a basic outline of my shader:

    Code (CSharp):
    1. Shader "World/Glass"
    2. {
    3.     Properties { /* some properties here*/ }
    4.  
    5.     SubShader
    6.     {
    7.         Tags
    8.         {
    9.            "Queue"      = "AlphaTest"
    10.            "RenderType" = "Transparent"
    11.         }
    12.  
    13.         Pass
    14.         {
    15.             ColorMask 0
    16.         }
    17.  
    18.         Pass
    19.         {
    20.             Name "BASE"
    21.  
    22.             ZWrite Off
    23.             Blend SrcAlpha OneMinusSrcAlpha
    24.  
    25.             Tags
    26.             {
    27.                 "LightMode" = "Always"
    28.             }
    29.  
    30.             CGPROGRAM
    31.             /* some simple shader stuff here */
    32.             ENDCG
    33.         }
    34.     }
    35. }
    36.  
    I can give you the complete code, if you want but trust me, it's nothing fancy.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    AlphaTest is an opaque queue, like Geometry, Background, and any queue 0 through 2500. Opaque queues are rendered in front to back order.

    Transparent is a, well, transparent queue, along with Overlay and all queues after 2500. Transparent queues are sorted back to front.

    Front to back sorting means the objects closest to the camera are rendered first with objects far away rendering last. This is done actually specifically for the reason your shader is working like you expect, which is ZTest is rejecting pixels where the depth has already been written to.

    Back to front sorting is as you can likely guess there opposite with objects furthest from the camera rendered first and objects closest to the camera rendered last. This is because it's expected that these objects will not have the benefit of the depth buffer for sorting and can be seen through each other so you don't want ZTest rejecting pixels anyway.

    So in you're case you have transparent objects but you want them to sort and depth reject like opaque, so you'll need to use AlphaTest, or a queue up to 2500, for it to sort in a way that works for how you want. Alternatively you could use two shaders in different queues to do the depth write and the color, or you could manually resort using renderer.sortingOrder.
     
  3. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    265
    Thank you again but I don't know. There is something I still don't understand or there is something we are both missing. I admit that I didn't know that even the opaque render queues are sorted but even then shouldn't it still work as I expected? Imagine two separate transparent walls crossing each other. Unity has to draw one of these walls first, no matter if sorted back to front or front to back, so the back of one of these walls should be visible through the other wall no matter which render queue I am using, right? But this is what I get:


    In case the image doesn't show up: http://fs5.directupload.net/images/170301/z8chi4sx.gif

    How is that possible by just sorting differently?
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    Unity's sorting doesn't always sort how you expect due to batching, bounds calculations, and some other Unity oddness. I would suggest you look at the scene using the frame debugger to see exactly what order it's rendering stuff in the scene. I think it'll become much more obvious once you step through and see it update.
     
  5. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    265
    Thanks for the hint to use the frame debugger. I never used it before to be honest. I finally managed to find the source for my transparency problem.

    The AlphaTest queue draws all the depth mask passes first and then all the corresponding base passes. The Transparent queue, however, draws the depth mask for one object and immediately after that its corresponding base pass. After that the next depth mask pass is rendered and again its corresponding base pass and so forth...

    So the transparent render queue consumes all passes of one object first before going to the next one! O_O This makes a depth mask pass useless in that queue. How is one supposed to know that?
     
    Last edited: Mar 2, 2017
    a436t4ataf likes this.
  6. Garrett_orious

    Garrett_orious

    Joined:
    Nov 16, 2016
    Posts:
    3
    This post saved me, thank you BrightBit!
     
    Scriptwonder likes this.