-->

分類

2017年2月12日 星期日

Notes about depth texture(using Unity shader code)

Depth texture used for effects like fog normally uses camera's depth texture, the shader code is as the following:

float depth01 = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, i.depthUV)));

Then you get the float in the range (0,1) for the depth value.

But the problem is that the depth texture of camera doesn't contains information about transparent objects, so we need to use fragment's depth in clip space, the shader code is as the following:

    struct appdata 
   {
          float4 vertex : POSITION;
  half2 texcoord : TEXCOORD0;
    };

    struct v2f 
    {
   float4 pos : SV_POSITION;
   float2 uv: TEXCOORD0;
        float2 depthUV : TEXCOORD1;
        float3 cameraToFarPlane : TEXCOORD2;
    float4 screenPos : TEXCOORD3;
    };
    
   v2f vert(appdata v) 
  {
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
o.screenPos = ComputeScreenPos(o.pos);
       ...
  }

  fixed4 frag (v2f i) : SV_Target 
 {
float depth01 = i.screenPos.w / (_ProjectionParams.z - _ProjectionParams.y);//normalize to the range(0,1)
  //i.screenPos.w: depth(z) in camera space, range(n, f), i think(could be wrong). Please check http://blog.csdn.net/zhao_92221/article/details/46844267 and http://www.songho.ca/opengl/gl_projectionmatrix.html for details. I guess unity uses projection matrix to map (n,f) to (0,1), could be wrong
  //_ProjectionParams.z - _ProjectionParams.y: camera far - near
  }

One use case of these two different values is that you can use it to measure the thickness of the transparent objects(e.g. the depth of water object). Simply use the depth for fragment in clip space to subtract the depth in camera's depth texture.