Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Why isn't an object with my custom material applied drawn on camera depth texture?

Discussion in 'Shaders' started by SpectreSpect, Jan 24, 2023.

  1. SpectreSpect

    SpectreSpect

    Joined:
    Jul 13, 2021
    Posts:
    17
    I try to make an outline effect. I've got some results, but for some reason the effect only works for objects with the standart material applied.

    It turns out that the reason is that objects with my custom material are not drawn on the depth texture.

    It looks like that.


    The outline works due to the depth texture. But for some reason the left object isn't drawn on the texture, so outline effect doesn't work​

    As you can see, only the right object (with the standart material) has an outline. But the left one doesn't have it.

    Here is the code of my material shader:

    Code (CSharp):
    1. Shader "Unlit/RegionShader"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.         _RegionColor ("Region color", Color) = (1,1,1,1)
    7.         _ShadowColor ("Shadow color", Color) = (0.5, 0.5, 0.5, 0.5)
    8.     }
    9.     SubShader
    10.     {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 100
    13.  
    14.  
    15.         Pass
    16.         {
    17.            
    18.             CGPROGRAM
    19.             #pragma vertex vert
    20.             #pragma fragment frag
    21.             #pragma multi_compile_fog
    22.  
    23.             #include "UnityCG.cginc"
    24.  
    25.             struct appdata
    26.             {
    27.                 float4 vertex : POSITION;
    28.                 float4 color : COLOR;
    29.                 float2 uv : TEXCOORD0;
    30.             };
    31.  
    32.             struct v2f
    33.             {
    34.                 float2 uv : TEXCOORD0;
    35.                 UNITY_FOG_COORDS(1)
    36.                 float4 vertex : SV_POSITION;
    37.                 float4 color : COLOR;
    38.             };
    39.  
    40.             sampler2D _MainTex;
    41.             float4 _MainTex_ST;
    42.             float4 _RegionColor;
    43.             float4 _ShadowColor;
    44.  
    45.             v2f vert (appdata v)
    46.             {
    47.                 v2f o;
    48.                 o.vertex = UnityObjectToClipPos(v.vertex);
    49.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    50.                 o.color = v.color;
    51.                 UNITY_TRANSFER_FOG(o,o.vertex);
    52.                 return o;
    53.             }
    54.  
    55.             fixed4 frag (v2f i) : SV_Target
    56.             {
    57.                 fixed4 col = tex2D(_MainTex, i.uv);
    58.                 UNITY_APPLY_FOG(i.fogCoord, col);
    59.                 return i.color;
    60.             }
    61.             ENDCG
    62.         }
    63.     }
    64. }
    And, also the outline post effect shader:

    Code (CSharp):
    1. Shader "Unlit/RegionShader"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.         _RegionColor ("Region color", Color) = (1,1,1,1)
    7.         _ShadowColor ("Shadow color", Color) = (0.5, 0.5, 0.5, 0.5)
    8.     }
    9.     SubShader
    10.     {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 100
    13.  
    14.  
    15.         Pass
    16.         {
    17.            
    18.             CGPROGRAM
    19.             #pragma vertex vert
    20.             #pragma fragment frag
    21.             #pragma multi_compile_fog
    22.  
    23.             #include "UnityCG.cginc"
    24.  
    25.             struct appdata
    26.             {
    27.                 float4 vertex : POSITION;
    28.                 float4 color : COLOR;
    29.                 float2 uv : TEXCOORD0;
    30.             };
    31.  
    32.             struct v2f
    33.             {
    34.                 float2 uv : TEXCOORD0;
    35.                 UNITY_FOG_COORDS(1)
    36.                 float4 vertex : SV_POSITION;
    37.                 float4 color : COLOR;
    38.             };
    39.  
    40.             sampler2D _MainTex;
    41.             float4 _MainTex_ST;
    42.             float4 _RegionColor;
    43.             float4 _ShadowColor;
    44.  
    45.             v2f vert (appdata v)
    46.             {
    47.                 v2f o;
    48.                 o.vertex = UnityObjectToClipPos(v.vertex);
    49.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    50.                 o.color = v.color;
    51.                 UNITY_TRANSFER_FOG(o,o.vertex);
    52.                 return o;
    53.             }
    54.  
    55.             fixed4 frag (v2f i) : SV_Target
    56.             {
    57.                 fixed4 col = tex2D(_MainTex, i.uv);
    58.                 UNITY_APPLY_FOG(i.fogCoord, col);
    59.                 return i.color;
    60.             }
    61.             ENDCG
    62.         }
    63.     }
    64. }
     
    AkumetsuRin likes this.
  2. AkumetsuRin

    AkumetsuRin

    Joined:
    Apr 12, 2019
    Posts:
    3
    I have the same question. I use Unity 2021 and URP. I want to use a camera depth texture in my post process effects. But opaque objects with my custom shaders are not in the texture, only with standard materials or shader graph materials. I tried to add DepthOnly and ShadowCaster passes, but it didn't help.
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    @SpectreSpect Your shader needs a shadowcaster pass. The easiest way to do that, as long as you’re not modifying the vertex positions or adding alpha testing, is to add a
    Fallback
    shader. For most things you want this just before the last
    }
    in your shader:
    FallBack "Legacy Shaders/VertexLit"


    @AkumetsuRin You’ll need those depth only and shadow caster passes. The depth only one is used for the camera depth texture. You may also need a depth normal pass. URP shaders don’t generally use a fallback in the same way as the built in pipeline, so instead I’d just copy the shader passes as they are from the simple lit shader.
    https://github.com/Unity-Technologi...-pipelines.universal/Shaders/SimpleLit.shader
     
    IgorAherne likes this.
  4. apaer

    apaer

    Joined:
    Jan 23, 2018
    Posts:
    9
    @bgolus.
    It certainly fixes the problem, but at what expense! According to editor Stats window:

    1. It adds an additional pass
    2. It doubles triangles count
    3. It doubles vertices count
    4. It adds a shadow caster


    For those who builds a game for a mobile device, sweats to optimise terrain to look good under constraints, this one is a suicidal attempt. It is a pity this one is the best we can.
     
    Last edited: Feb 11, 2024
  5. apaer

    apaer

    Joined:
    Jan 23, 2018
    Posts:
    9
    By the way, inside the builtin RP, switching the settings from Forward to Deferred Rendering path provides the same fix, without doubling triangles and vertices, or adding shadow caster, according to editor Stats.

    No need to include "Camera.main.depthTextureMode = ..." line either.

    Furthermore, switching to Deferred rendering only ever adds 2 extra calls, while the previous "shadow casting" solution doubles the calls for each material(if not object), that needs to be in the Depth texture !

    MSAA doesn't work out of the box with Deferred rendering, neither with Forward rendering textiles. Both ways have to have a hardware that supports Depth Texture. Deferred rendering is better scales with lighting ... why not try?

    I just hope there are even better (more efficient) ways of accessing the depth data inside the frame and inside the GPU.
     
    Last edited: Feb 11, 2024