Search Unity

Resolved Custom depth map with custom matrices.

Discussion in 'Shaders' started by Lexikus, Feb 3, 2021.

  1. Lexikus

    Lexikus

    Joined:
    Mar 3, 2018
    Posts:
    2
    I've been fighting with this for a while now and I have no ideas anymore.

    I want to create a depth map/texture with my shader. I don't use the macros/functions from unity because they are based on the camera's matrices (I guess). I use my matrices. I get the scene drawn to a texture completely fine, but I can't create a depth texture from it.

    I tried multiple ways to achieve this. Here some code to get a better understanding of my problem. this will be called every update:

    Code (CSharp):
    1.  // Remember the current texture and set our own as "active".
    2. RenderTexture prevRT = RenderTexture.active;
    3. RenderTexture.active = renderTexture;
    4.  
    5. // Set material as "active". Without this, Unity editor will freeze.
    6. material.SetPass(0);
    7.  
    8. // Push the projection matrix
    9. GL.PushMatrix();
    10.  
    11. // `projectionMatrix` is an ortho projection
    12. GL.LoadProjectionMatrix(projectionMatrix);
    13.  
    14. // `viewMatrix` is a TRS matrix
    15. material.SetMatrix("_viewMatrix", viewMatrix);
    16.  
    17. // Clear the texture
    18. GL.Clear(true, true, Color.white);
    19.  
    20.  
    21. // bunch of meshes
    22. foreach (var mesh in meshes){
    23.     Quaternion rotation = Quaternion.Euler(mesh.rotation);
    24.     // Create the model matrix
    25.     Matrix4x4 objectMatrix = Matrix4x4.TRS(mesh.position, rotation, mesh.scale);
    26.  
    27.     // Draw the mesh!
    28.     Graphics.DrawMeshNow(mesh.mesh, objectMatrix);
    29. }
    30.  
    31. // Pop the projection matrix to set it back to the previous one
    32. GL.PopMatrix();
    33.  
    34. // Re-set the RenderTexture to the last used one
    35. RenderTexture.active = prevRT;
    So this draws everything fine into a RenderTexture which has a shader attached. The shader is an unlit shader which is very basic.

    Code (CSharp):
    1. //...
    2. SubShader
    3. {
    4.     Pass
    5.     {
    6.         CGPROGRAM
    7.         #pragma vertex vert
    8.         #pragma fragment frag
    9.  
    10.         #include "UnityCG.cginc"
    11.  
    12.         float4x4 _viewMatrix;
    13.  
    14.         struct appdata
    15.         {
    16.             float4 vertex : POSITION;
    17.         };
    18.  
    19.         struct v2f
    20.         {
    21.             float4 vertex : SV_POSITION;
    22.             float2 depth : DEPTH;
    23.         };
    24.  
    25.         v2f vert (appdata v)
    26.         {
    27.             v2f o;
    28.             float4 vertex = v.vertex;
    29.             float4x4 mv = mul(_viewMatrix, unity_ObjectToWorld);
    30.             float4x4 mvp = mul(UNITY_MATRIX_P, mv);
    31.             vertex = mul(mvp, vertex);
    32.             o.vertex = vertex;
    33.             o.depth = vertex.zw;
    34.             return o;
    35.         }
    36.  
    37.         fixed4 frag (v2f i) : SV_Target
    38.         {
    39.             half depth = i.depth.x / i.depth.y;
    40.             return fixed4(depth,depth,depth,1);
    41.         }
    42.         ENDCG
    43.     }
    44. }
    45. //...

    I also tried to just return 0 in the pixel shader by disabling Cull Off and ZWrite On. The result that I get is always a black or transparent texture where the meshes are. So, there is no depth.

    Has someone an idea how I can create a depth map with custom matrices? I'd appreciate any help.
     
  2. Lexikus

    Lexikus

    Joined:
    Mar 3, 2018
    Posts:
    2
    In the meanwhile, I got help somewhere else and I wanted to post the solution in case someone else might have the same problem. See comments for the changes.

    Code (CSharp):
    1. struct v2f
    2. {
    3.     float4 vertex : SV_POSITION;
    4.     // this line below is new
    5.     float depth : DEPTH;
    6. };
    7.  
    8. v2f vert (appdata v)
    9. {
    10.     v2f o;
    11.     float4 vertex = v.vertex;
    12.     float4x4 mv = mul(_viewMatrix, unity_ObjectToWorld);
    13.     float4x4 mvp = mul(UNITY_MATRIX_P, mv);
    14.     vertex = mul(mvp, vertex);
    15.     o.vertex = vertex;
    16.     // this line below is new
    17.     o.depth = -mul(mv, v.vertex).z * _ProjectionParams.w;
    18.     return o;
    19. }
    20.  
    21. fixed4 frag (v2f i) : SV_Target
    22. {
    23.     // this line below is new
    24.     half depth = i.depth;
    25.     return fixed4(depth,depth,depth,1);
    26. }
     
    fehencke likes this.