Search Unity

  1. Unity 2020.1 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Depth Pass is offset in Game Camera but not Scene Camera

Discussion in 'Shaders' started by Max_Chaos, Jul 24, 2020.

  1. Max_Chaos

    Max_Chaos

    Joined:
    Dec 18, 2013
    Posts:
    12
    Hi All

    I am writing a volume shader and need help getting the correct Zdepth Screen Position so as i march through the volume and hit another object with the same Zdepth, it will stop marching and return.

    The shader is attached to the game object (cube) ray marching a torus at the moment.

    Zdepth mapping is working great in the scene view, but game view it's offset for some reason in the y direction.

    As you can tell I have tried everything and this code works the best.

    Code (CSharp):
    1. float _depth = LinearEyeDepth (tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPosition)).r);
    Any help would be much appreciated. Even if i have to just offset the depthmap texture some how manually that will do.

    Code (CSharp):
    1.  void frag(v2f i, out fixed4 color : SV_TARGET, out float depth : SV_Depth)//fixed4 frag (v2f i) : SV_Target
    2.             {
    3. //                float nonLinearDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);
    4.   //              float depth = LinearEyeDepth(nonLinearDepth);
    5.                 float viewLength = length(i.viewVector);
    6.                 float3 rayDir = i.viewVector / viewLength;
    7.  
    8.                 float2 textureCoordinate = i.screenPosition.xy / i.screenPosition.w;
    9.                 float aspect = _ScreenParams.x / _ScreenParams.y;
    10.                 textureCoordinate.x = textureCoordinate.x * aspect;
    11.                 textureCoordinate = TRANSFORM_TEX(textureCoordinate, _MainTex);
    12.                
    13.                 // Depth and cloud container intersection info:
    14.                 //float nonlin_depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.screenPosition);
    15. //                textureCoordinate = TRANSFORM_TEX(textureCoordinate, _CameraDepthTexture);
    16.                 //float _depth = LinearEyeDepth(nonlin_depth) * viewLength;
    17.                 float _depth = LinearEyeDepth (tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPosition + depthOffset)).r);
    18. //                float rawZ = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPosition / i.screenPosition.w));
    19. //                textureCoordinate = TRANSFORM_TEX(textureCoordinate, _CameraDepthTexture);
    20.                 //float corrawz = tex2D(_CameraDepthTexture, textureCoordinate);
    21. //                float _depth = LinearEyeDepth(rawZ);
    22.  
    Depth01.PNG Depth02.PNG
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    8,979
    How are you calculating the screen position?
     
  3. Max_Chaos

    Max_Chaos

    Joined:
    Dec 18, 2013
    Posts:
    12
    Code (CSharp):
    1. v2f object;
    2.                 object.vertex = UnityObjectToClipPos(v.vertex);
    3.  
    4.                 //Mesh UV's
    5.                 object.uv = TRANSFORM_TEX(v.uv, _MainTex);
    6.  
    7.                 object.rayOrigin = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1));
    8.                 object.hitPos = v.vertex;
    9.  
    10.                 //Tri Planar UV's????
    11.                 float3 viewVector = mul(unity_CameraInvProjection, float4(v.uv * 2 - 1, 0, -1));
    12.                 object.viewVector = mul(unity_CameraToWorld, float4(viewVector,0));
    13.                
    14.                 //Screen Space UV's
    15.                 object.screenPosition = ComputeScreenPos(object.vertex);
    16.                 return object;
     
  4. Max_Chaos

    Max_Chaos

    Joined:
    Dec 18, 2013
    Posts:
    12
    This code gave me the same result, work fine in scene few, same y offset in game camera.

    Code (CSharp):
    1. float2 textureCoordinate = i.screenPosition.xy / i.screenPosition.w;
    2. SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, textureCoordinate);
    3. float _depth = LinearEyeDepth(corrawz);
    This worked perfectly for maping color to the object, but can't get it do do the same for depth.

    Code (CSharp):
    1. float2 textureCoordinate = i.screenPosition.xy / i.screenPosition.w;
    2. float aspect = _ScreenParams.x / _ScreenParams.y;
    3. textureCoordinate.x = textureCoordinate.x * aspect;
    4. textureCoordinate = TRANSFORM_TEX(textureCoordinate, _MainTex);
    5.            
    6. fixed4 col = tex2D(_MainTex, textureCoordinate);
     
  5. Max_Chaos

    Max_Chaos

    Joined:
    Dec 18, 2013
    Posts:
    12
    Here is the raymarching controller and shader. Just Add the shader via material and controller to a normal cube in a new scene with a light. Add another cube with default material and floor and see if it works for you.

    I'm using 2019.4.3f
     

    Attached Files:

  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    8,979
    So it matters significantly if you’re planning on doing this via a Blit or object rendered in the world. If you’re using a Blit, you have to reconstruct the view direction from the inverse projection matrix, and sample the depth texture using the vertex UVs. If you’re doing this as a mesh rendered in the world, then you’ll want to get the view vector from the actual vertex positions and sample the depth texture from the screen space position you’re already using to sample with. As for why it’s offset / upside down, try outputting the raw depth using the screen position as the shader’s color output and I suspect you’ll find it’s correct ... again, as long as you’re doing this on an object rendered in the world, and not as a Blit.

    If you look at the built in shaders that use the depth texture, like the particle shaders, you’ll see they’re not doing anything more.
    https://github.com/TwoTailsGames/Un...ultResourcesExtra/Particle Alpha Blend.shader

    My guess is the real problem is with your view vector being calculated incorrectly. If you use the camera projection matrix (
    unity_CameraProjection
    ), that may indeed be flipped vs the actual projection matrix used for rendering (
    UNITY_MATRIX_P
    ). And when rendering an object in the scene, there’s no reason to use the inverse camera projection matrix to calculate the view vector since the object exists in 3D space. In fact there’s even a built in function for getting the object space view dir!
    o.viewVector = ObjSpaceViewDir(v.vertex);


    Also, random aside, the “
    o
    ” in a vertex shader is usually short for “output”, not “object”.
     
  7. Max_Chaos

    Max_Chaos

    Joined:
    Dec 18, 2013
    Posts:
    12
    Thanks bgolus. I am using the shader on an object. This is very helpful. I managed to get it working as well as pass a 3D texture to the object as well which scales and rotates with the object.

    float4 sampledColor = ControlTexture.SampleLevel(samplerControlTexture, rayPos * scale + texture_offset, 0);

    DepthFixed.PNG
     
unityunity