Search Unity

Material in AlphaTest render queue writes to depth buffer although ZWrite is Off!

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

  1. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    265
    The subtle differences in Unity's render queues are driving me crazy! I want to create a transparent material that shows the depth of objects behind it but for some reason it only works in the "Transparent" render queue.

    It looks as if objects in opaque render queues write to the depth buffer before the actual shader is evaluated.

    Here's a small animation to illustrate my problem:



    Is this a bug? I wasn't able to find documentation about this "feature".

    Here's the shader I was using:

    Code (CSharp):
    1. Shader "Custom/AlphaTestShader"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (1,1,1,1)
    6.         _From  ("From",  Range (0, 1)) = 0
    7.         _To    ("To",    Range (0, 1)) = 0.02
    8.     }
    9.  
    10.     SubShader
    11.     {
    12.         Tags
    13.         {
    14.             "Queue"      = "Geometry"
    15.         }
    16.  
    17.         LOD 200
    18.         ZWrite Off
    19.  
    20.         CGPROGRAM
    21.         #pragma surface surf Standard vertex:vert decal:blend
    22.         #pragma target 3.0
    23.  
    24.         uniform sampler2D_float _CameraDepthTexture; //Depth Texture
    25.  
    26.         float _From;
    27.         float _To;
    28.  
    29.         struct Input
    30.         {
    31.             float2 uv_MainTex;
    32.             float4 screenUV;
    33.         };
    34.  
    35.         fixed4 _Color;
    36.  
    37.         void vert(inout appdata_full v, out Input o)
    38.         {
    39.             UNITY_INITIALIZE_OUTPUT(Input, o);
    40.  
    41.             float4 screenPos = mul(UNITY_MATRIX_MVP, v.vertex);
    42.             float4 screenUV = ComputeScreenPos(screenPos);
    43.  
    44.             COMPUTE_EYEDEPTH(screenUV.z);
    45.  
    46.             o.screenUV = screenUV;
    47.         }
    48.  
    49.         float Remap(float from1, float to1, float from2, float to2, float value)
    50.         {
    51.             return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
    52.         }
    53.  
    54.         void surf (Input IN, inout SurfaceOutputStandard o)
    55.         {
    56.             float sceneZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenUV)));
    57.  
    58.             o.Albedo = Remap(0, 1, _From, _To, sceneZ);
    59.             o.Alpha = 1;
    60.         }
    61.  
    62.         ENDCG
    63.     }
    64.  
    65.     FallBack "Diffuse"
    66. }
    If this happens on purpose, do you know why? Can the devs add some documentation about the differences between the render queues, please. It is really annoying to stumble upon such things. As you can see in this thread there is at least one more difference in the render queue behaviour related to the order in which shader passes are evaluated: Difference between AlphaTest and Transparent RenderQueue?
     
    Tudor likes this.
  2. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    265
    Okay, it's my mistake or my incomplete understanding of the shader mechanisms. The last line of the shader above indicates a "Diffuse" fallback shader. This shader contains a shadow caster pass that is evaluated before my main pass and that's the reason for my problem, so removing this line, i.e. removing the shadow caster pass, makes the material show the depth of objects behind itself even in the AlphaTest render queue.
     
    Tudor likes this.
  3. Tudor

    Tudor

    Joined:
    Sep 27, 2012
    Posts:
    150
    Holy cow `FallBack "Diffuse"` is not a fallback at all but hidden builtin and ALWAYS ACTIVE magic? I was struggling with this alphaTest depth writing for 2 days and never would have found out without your post. :/

    Some of these things could really use like a line of comment describing what it does.
     
    Last edited: Jun 9, 2017