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

Render Depth Shader

Discussion in 'Shaders' started by pmaloo, Aug 23, 2016.

  1. pmaloo

    pmaloo

    Joined:
    Jan 25, 2015
    Posts:
    35
    I am fairly new to shaders, and just trying out simple examples to render the depth. I took the following code from https://docs.unity3d.com/Manual/SL-DepthTextures.html

    Code (CSharp):
    1.  
    2. Shader "Render Depth" {
    3.     SubShader {
    4.         Tags { "RenderType"="Opaque" }
    5.         Pass {
    6.             CGPROGRAM
    7.  
    8.             #pragma vertex vert
    9.             #pragma fragment frag
    10.             #include "UnityCG.cginc"
    11.  
    12.             struct v2f {
    13.                 float4 pos : SV_POSITION;
    14.                 float2 depth : TEXCOORD0;
    15.             };
    16.  
    17.             v2f vert (appdata_base v) {
    18.                 v2f o;
    19.                 o.pos = UnityObjectToClipPos(v.vertex);
    20.                 UNITY_TRANSFER_DEPTH(o.depth);
    21.                 return o;
    22.             }
    23.  
    24.             half4 frag(v2f i) : SV_Target {
    25.                 UNITY_OUTPUT_DEPTH(i.depth);
    26.             }
    27.             ENDCG
    28.         }
    29.     }
    30. }

    I used the following code in my script to render the depth during run-time:
    Code (CSharp):
    1.         mCamera = GetComponent<Camera> ();
    2.         mCamera.depthTextureMode |= DepthTextureMode.Depth;
    3.         mCamera.SetReplacementShader (shader, null);
    However, I am getting a completely black output instead of a smooth monochrome gradient indicating the depth. Can someone please point out where I am going wrong?

    Thanks
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    First off a camera's depth texture mode sets what kind of depth texture you want Unity to generate for you. Presumably if you're using this camera to generate your own custom depth you actually don't want that value set to anything at all.

    Secondly a quote from that Unity documentation:
    Emphasis mine. In short for rendering a custom depth texture those macros don't render anything in the camera view. The reason is cameras by default have two "textures", the color that you see, and the depth which is used for sorting. Generally you can't really see the depth texture as it's not what the camera visually displays, and since those macros aren't rendering anything but black that's all you see.

    What you need to do is set a render target or render texture on the camera before it renders, then you'll get a render texture with a black color component and a depth component with depth! If you use the Frame Debugger window you can even see what's in it!

    However that's all you can do because while Unity has that page with those useful macros and a lot of code for dealing with depth buffers as far as I can tell the one thing they don't expose is a way to allow the depth to be accessible by a shader! Unity is capable of doing this, it's how it's own internal depth textures are generated, but there's no way for user code to do this, so that bolded statement is even more accurate than they intended it to be.

    So what to do? Well you can try to find those macros in the built in shader source and see what they do when there isn't a native depth texture, which is render out the depth to the color value like you were expecting them to. I think you can even set the color component of a render texture to be a depth texture format, or just use an RHalf or RFloat.

    If this seems odd or silly, I'm pretty sure this is what Valve did for their Labs Renderer. And if Valve is having to resort to hacky work around a like that you know it's the only way.
     
    Theurgistor and pmaloo like this.
  3. pmaloo

    pmaloo

    Joined:
    Jan 25, 2015
    Posts:
    35
    Thanks for a detailed answer. I am not that great with shaders but I think I got the gist of it.

    If I understood right, there is no way to get the depth without first rendering to a render texture. I have to do post-processing using an image effect.