Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  3. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question about Transparent Depth Prepass when handling multiple transparent objects.

Discussion in 'Graphics Experimental Previews' started by alexandre-fiset, Aug 8, 2019.

  1. alexandre-fiset

    alexandre-fiset

    Joined:
    Mar 19, 2012
    Posts:
    716
    I am not sure if that is "as designed", but the Transparent Depth Prepass option in the material settings, which is supposed to improve sorting, actually makes transparent objects invisible when they are behind another transparent object.

    This is without the option:
    upload_2019-8-8_16-27-14.png

    And now with it:

    upload_2019-8-8_16-28-17.png

    Is this something normal or should I fill a bug about this?
     
  2. PeterAndrewB

    PeterAndrewB

    Joined:
    Nov 5, 2019
    Posts:
    7
    Noticed this too, it doesn't make a lot of sense
     
  3. kronovecta

    kronovecta

    Joined:
    Nov 15, 2020
    Posts:
    1
    Apologies if I'm necrobumping, but have been dealing with this recently (first post here)

    This seems like a render order issue to me.
    When writing to the depth buffer in a transparent shader (using "depth pre-pass") - I believe its important to set render order.

    In this screenshort (and seems like in yours) - sorting is done front-to-back (which is wrong)
    • Front cube's renderQueue = 3000 (render first)
    • Rear cube's renderQueue = 3001 (render second)
    upload_2021-1-31_21-28-29.png
    • Front cube is rendered first, and writes to depth buffer.
    • Background cube is rendered second. The occluded fragments fail the depth test (against front cube) and get discarded.

    When setting render order to "back-to-front", this is resolved. (occluded fragments are no longer culled)
    upload_2021-1-31_21-31-33.png

    To resolve this, the render order needs to be set back-to-front. (So rear cube is rendered first, and is not culled in depth test)

    For transparent objects - I believe Unity performs back-to-front sorting automatically.
    (So transparent shaders with identical render order will render back-to-front) - Would love to get a confirmation on this.

    This is the shader I am using, with a depth pass followed by surface shader pass:
    Code (CSharp):
    1. Shader "Custom/surfaceTransparent_b"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (1,1,1,1)
    6.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    7.         _Metallic ("Metallic", Range(0,1)) = 0.0
    8.         _Alpha ("Alpha", Float) = 1.0
    9.     }
    10.     SubShader
    11.     {
    12.         Tags {"Queue"="Transparent" "RenderType"="Transparent"}
    13.         LOD 200
    14.  
    15.         // first pass writes to depth buffer only (make sure sorting is done back-to-front! otherwise occluded fragments will get discarded!)
    16.         Pass
    17.         {
    18.             ZWrite On
    19.             // disable rendering to color channels
    20.             ColorMask 0
    21.  
    22.         }
    23.  
    24.         // second pass renders frag color and alpha ( using transparent surface shader )
    25.         ZWrite Off
    26.         Blend SrcAlpha OneMinusSrcAlpha
    27.         BlendOp Add
    28.  
    29.         CGPROGRAM
    30.         // Physically based Standard lighting model, and enable shadows on all light types
    31.         #pragma surface surf Standard fullforwardshadows alpha:fade
    32.  
    33.         // Use shader model 3.0 target, to get nicer looking lighting
    34.         #pragma target 3.0
    35.  
    36.         struct Input
    37.         {
    38.             float2 uv_MainTex;
    39.         };
    40.  
    41.         half _Glossiness;
    42.         half _Metallic;
    43.         fixed4 _Color;
    44.         float _Alpha;
    45.  
    46.         // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
    47.         // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
    48.         // #pragma instancing_options assumeuniformscaling
    49.         UNITY_INSTANCING_BUFFER_START(Props)
    50.             // put more per-instance properties here
    51.         UNITY_INSTANCING_BUFFER_END(Props)
    52.  
    53.         void surf (Input IN, inout SurfaceOutputStandard o)
    54.         {
    55.             // Albedo comes from a texture tinted by color
    56.             fixed4 c = _Color;
    57.             o.Albedo = c.rgb;
    58.             // Metallic and smoothness come from slider variables
    59.             o.Metallic = _Metallic;
    60.             o.Smoothness = _Glossiness;
    61.             o.Alpha = _Alpha;
    62.         }
    63.         ENDCG
    64.  
    65.  
    66.     }
    67.     FallBack "Diffuse"
    68. }
    69.  
    Including this depth-pre pass is useful in making sure that complex transparent meshes can have depth-sorting, to prevent such sorting issues:
    sortingissues.PNG

    This can be solved by writing to the depth buffer in a depth-only shader pass, followed by normal shader pass:
    depthonlypass.PNG
     
    Last edited: Jan 31, 2021
  4. berniegp

    berniegp

    Unity Technologies

    Joined:
    Sep 9, 2020
    Posts:
    42
    While your post is very informative @kronovecta, this is not quite what the Transparent Depth Prepass option does. The first set of images in this thread is indeed the by design behavior. Only the nearest transparent sphere will be rendered for each pixel with the prepass.

    Transparent Depth Prepass allows to write to the depth buffer to affect depth tests in the following pipeline stages (e.g. Transparents rendering). Note that the depth pyramid (the depth texture you can read in a shader) will not contain the depth information from the Transparent Depth Prepass since it is generated much earlier in the pipeline.

     
    ariel_kuo_unity3d likes this.