Question about Transparent Depth Prepass when handling multiple transparent objects.

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:

And now with it:

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

Noticed this too, it doesn’t make a lot of sense

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)

  • 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)

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:

Shader "Custom/surfaceTransparent_b"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _Alpha ("Alpha", Float) = 1.0
    }
    SubShader
    {
        Tags {"Queue"="Transparent" "RenderType"="Transparent"}
        LOD 200

        // first pass writes to depth buffer only (make sure sorting is done back-to-front! otherwise occluded fragments will get discarded!)
        Pass
        {
            ZWrite On
            // disable rendering to color channels
            ColorMask 0

        }

        // second pass renders frag color and alpha ( using transparent surface shader )
        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha
        BlendOp Add

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows alpha:fade

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        struct Input
        {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
        float _Alpha;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = _Alpha;
        }
        ENDCG


    }
    FallBack "Diffuse"
}

Including this depth-pre pass is useful in making sure that complex transparent meshes can have depth-sorting, to prevent such sorting issues:

This can be solved by writing to the depth buffer in a depth-only shader pass, followed by normal shader pass:

5 Likes

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.

2 Likes