Search Unity

Resolved Proper way to compare two different depth values?

Discussion in 'Shaders' started by b1gry4n, Sep 11, 2020.

  1. b1gry4n

    b1gry4n

    Joined:
    Sep 11, 2013
    Posts:
    146
    In a custom render pass I am drawing a masks depth to a render texture. Later in a different custom render pass I want to read the mask depth value and compare it against camera depth. Right now I am doing:

    float val = maskDepth.r - depth > 0 ? 1 : 0;
    outColor = lerp(float4(1, 0, 0, 1), float4(0,1,0,1), val);


    Where maskDepth.r is from the previous pass and depth is from the camera depth. I know this isnt correct and the following image shows, but I am not sure how I could compare two depth values where its possible that the depth is identical or very close to identical.



    The mask is correct and the right side of the image is obstructed, but the issue is the Zfighting happening from the depth values being identical.
     
  2. Sh-Shahrabi

    Sh-Shahrabi

    Joined:
    Sep 28, 2018
    Posts:
    56
    Camera depth is not stored in linear values. I assume when you are manually writing the depth mask to a render target, you are using linear depth. You first need to decode the log scale depth buffer in to linear before actually doing the comparison. Unity has macros for this in UnityCG file. It looks like this


    Code (CSharp):
    1. // Z buffer to linear 0..1 depth
    2. inline float Linear01Depth( float z )
    3. {
    4.    return 1.0 / (_ZBufferParams.x * z + _ZBufferParams.y);
    5. }
    6. // Z buffer to linear depth
    7. inline float LinearEyeDepth( float z )
    8. {
    9.    return 1.0 / (_ZBufferParams.z * z + _ZBufferParams.w);
    10. }
     
  3. b1gry4n

    b1gry4n

    Joined:
    Sep 11, 2013
    Posts:
    146
    I am using PositionInputs which comes with a linear depth.
    float  linearDepth; // View space Z coordinate                              : [Near, Far]

    It also has device depth which produces the same result
    float  deviceDepth; // Depth from the depth buffer                          : [0, 1] (typically reversed)


    The issue is the zfighting that is happening from the 2 depth values I am comparing being identical or almost identical. I need a way to say "if mask depth is greater than camera depth, draw red, if they are the same or mask depth is less, draw green"

     
    Last edited: Sep 11, 2020
  4. b1gry4n

    b1gry4n

    Joined:
    Sep 11, 2013
    Posts:
    146
    I was hoping to get away with this method, but I think the solution is to just check depth in the mask pass before drawing the mask rather than checking after the mask has been drawn allowing me to completely skip this depth comparison.
     
  5. b1gry4n

    b1gry4n

    Joined:
    Sep 11, 2013
    Posts:
    146
    I revisited this because I wasnt satisfied with not at least solving it. I am new to shaders. This is the only way I could figure out how to get the desired result. Maybe there is a better way?

    Code (CSharp):
    1.                 float lerpVal = 0;
    2.                 outColor = float4(1, 0, 0, 1);
    3.                 if (0.1 - mask.g < 0)
    4.                 {
    5.                     lerpVal = 1;
    6.                     if (maskDepthVal - sceneDepthVal < 0.00001)
    7.                     {
    8.                         lerpVal = 0;
    9.                     }
    10.                 }
    11.                 outColor = lerp(float4(1, 0, 0, 1), float4(0, 1, 0, 1), lerpVal);
    This is how I am using it in my shader
    Code (CSharp):
    1.  
    2.                 //mask.g is the color mask I am using
    3.                 //maskDepthVal is the depth from the color mask
    4.                 //scenedepthval is the depth value from the camera
    5.                 mask.g = maskDepthVal - sceneDepthVal < 0.00001 ? mask.g : 0;
    6.                 clip(0.1 - mask.g);
     
    Last edited: Sep 12, 2020
  6. Skulltager

    Skulltager

    Joined:
    Aug 12, 2016
    Posts:
    27
    I have a problem that seems to be related related to what you've been doing here. I can't seem to figure out how you managed to calculate the maskDepthVal and sceneDepthVal. Do you still happen to have the entire shader script for this?