Search Unity

Custom sky box and depth mask shaders not working together

Discussion in 'Shaders' started by CharlieBudd, Sep 7, 2019.

  1. CharlieBudd

    CharlieBudd

    Joined:
    Jul 24, 2017
    Posts:
    17
    Hi there,

    Hoping somebody can see what I'm missing here.

    I've got a depth mask shader used to obscure certain objects. This works great, very simple. However I recently added a custom skybox shader in order to render a gradient as the background. This has lead to the depth mask material rendering black to the screen and objects drawn in front are not cleared. Code for both shaders and picture of problem below.

    Thanks for reading...

    Code (CSharp):
    1. Shader "Skybox/GradientSkybox"
    2. {
    3.     Properties
    4.     {
    5.         _TopColor("Top Color", Color) = (1, 1, 1, 1)
    6.         _BottomColor("Bottom Color", Color) = (0, 0, 0, 1)
    7.         _Angle("Angle", Range(0, 360)) = 0
    8.     }
    9.  
    10.     CGINCLUDE
    11.  
    12.     #include "UnityCG.cginc"
    13.  
    14.     struct appdata
    15.     {
    16.         float4 position : POSITION;
    17.     };
    18.  
    19.     struct v2f
    20.     {
    21.         float4 position : SV_POSITION;
    22.         float2 texcoord : TEXCOORD0;
    23.     };
    24.  
    25.     half4 _TopColor;
    26.     half4 _BottomColor;
    27.     half _Angle;
    28.  
    29.     v2f vert(appdata v)
    30.     {
    31.         v2f o;
    32.         o.position = UnityObjectToClipPos(v.position);
    33.         o.texcoord = 0.5 * (o.position.xy / o.position.w);
    34.         return o;
    35.     }
    36.  
    37.     half4 frag(v2f i) : COLOR
    38.     {
    39.         float2 uv = i.texcoord;
    40.  
    41.         float radians = _Angle * 0.01745329;
    42.         float2 rotation = float2(sin(radians), cos(radians));
    43.  
    44.         float topCoefficient    = dot( rotation, uv) + 0.5;
    45.         float BottomCoefficient = dot(-rotation, uv) + 0.5;
    46.  
    47.         half4 color = topCoefficient * _TopColor + BottomCoefficient * _BottomColor;
    48.  
    49.         return color;
    50.     }
    51.  
    52.     ENDCG
    53.  
    54.     SubShader
    55.     {
    56.         Tags{ "RenderType" = "Background" "Queue" = "Background" }
    57.  
    58.         Pass
    59.         {
    60.             ZWrite Off
    61.             Cull Off
    62.             Fog { Mode Off }
    63.             CGPROGRAM
    64.             #pragma fragmentoption ARB_precision_hint_fastest
    65.             #pragma vertex vert
    66.             #pragma fragment frag
    67.             ENDCG
    68.         }
    69.     }
    70.  
    71.     CustomEditor "GradientSkyboxInspector"
    72. }
    Code (CSharp):
    1. Shader "Unlit/DepthMask"
    2. {      
    3.     SubShader
    4.     {
    5.         Tags {"Queue" = "Geometry-10" }
    6.  
    7.         ColorMask 0
    8.         ZWrite On
    9.  
    10.         Pass {}
    11.     }
    12. }
    13.  

    upload_2019-9-7_8-20-18.png
     
  2. Namey5

    Namey5

    Joined:
    Jul 5, 2013
    Posts:
    188
    My first guess is that this is to do with draw order. For performance reasons, the skybox is drawn after opaque geometry to prevent overdraw - meaning that the skybox won't be drawn whenever something has written to the depth buffer before it. Ordinarily, this would be fine because you would have something drawn in its place, but in this case you write to the depth buffer without writing to the colour buffer. As such, the skybox rendering skips the mask's geometry, leaving nothing behind it (also explaining why objects in front appear to not be cleared). Not sure how you would get around this in the built-in render pipeline. Render queue for skyboxes doesn't do much because they are drawn separately after opaques anyway. I can only suggest not using a skybox, but instead having a regular sphere object that is always drawn in the background.
     
  3. thesanketkale

    thesanketkale

    Joined:
    Dec 14, 2016
    Posts:
    65
    Hi @Namey5, I am facing this same issue and need to stick to built-in render pipeline. Is it possible to work around this by having a custom render pipeline which is created extending the built-in render pipeline and changing the skybox rendering behaviour?