title: How to compute the radial distance of an object in a postprocessing vertex and fragment shader
body: <p>After hours of Google, copy-pasting codes and playing around, I still could not find a solution to my problem.</p>
  
  <p>I try to write a postprocessing shader using the vertex and fragment functions. My problem is that I do not know how to compute the radial distance of the current vertex to the camera position (or any other given position) in world coordinates.</p>
  
  <h2>My goal is the following:</h2>
  
  <p>Consider a very big 3D plane where the camera is on top and looks exactly down to the plane. I now want a postprocessing shader that draws a white line onto the plane, such that only those pixels that have a certain radial distance to the camera are painted white. The expected result would be a white circle (in this specific setup).</p>
  
  <p>I know how to do this in principal, but the problem is that I cannot find out how to compute the radial distance to the vertex.</p>
  
  <p>The problem here might be that this is a POSTPROCESSING shader. So this shader is not applied to a certain object. If I would do so, I could get the world coordinates of the vertex by using <code>mul(unity_ObjectToWorld, v.vertex)</code>, but for postprocessing shaders this gives a nonsense value.</p>
  
  <p>This is my debug code for this issue:</p>
  
  <pre class="lang-hlsl prettyprint-override"><code>Shader "NonHidden/TestShader"
  {
      Properties
      {
          _MainTex ("Texture", 2D) = "white" {}
      }
      SubShader
      {
          Tags { "RenderType"="Transparent" "Queue"="Transparent-1"}
          LOD 100
  
          ZWrite Off
  
          Pass
          {
              CGPROGRAM
              #pragma vertex vert
              #pragma fragment frag
              #pragma target 3.0
              #include "UnityCG.cginc"
  
              sampler2D _MainTex;
              sampler2D _CameraDepthTexture;
              uniform float4 _MainTex_TexelSize;
  
              // V2F
              struct v2f {
                  float4 outpos  : SV_POSITION;
                  float4 worldPos : TEXCOORD0;
                  float3 rayDir : TEXCOORD1;
                  float3 camNormal : TEXCOORD2;
              };
  
  
              // Sample Depth
              float sampleDepth(float2 uv) {
                  return Linear01Depth(
                          UNITY_SAMPLE_DEPTH(
                              tex2D(_CameraDepthTexture, uv)));
              }
  
  
              // VERTEX
              v2f vert (appdata_tan v)
              {
                  TANGENT_SPACE_ROTATION;
  
                  v2f o;
                  o.outpos = UnityObjectToClipPos(v.vertex);
                  o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                  o.rayDir = mul(rotation, ObjSpaceViewDir(v.vertex));
                  o.camNormal = UNITY_MATRIX_IT_MV[2].xyz;
                  return o;
              }
  
              // FRAGMENT
              fixed4 frag (v2f IN) : SV_Target
              {
                  // Get uv coordinates
                  float2 uv = IN.outpos.xy * (_ScreenParams.zw - 1.0f);
  
                  // Flip y if necessary
                  #if UNITY_UV_STARTS_AT_TOP
                  if (_MainTex_TexelSize.y &lt; 0)
                  {
                      uv.y = 1 - uv.y;
                  }
                  #endif
  
                  // Get depth
                  float depth = sampleDepth(uv);
  
                  // Set color
                  fixed4 color = 0;
                  if(depth.x &lt; 1)
                  {
                      color.r = IN.worldPos.x;
                      color.g = IN.worldPos.y;
                      color.b = IN.worldPos.z;
                  }
  
                  return color;
              }       
              ENDCG
          }
      }
  }
  </code></pre>
  
  <h2>CurrentState</h2>
  
  <p>This image shows the result when the camera looks down on the plane:
  <a href="https://i.stack.imgur.com/8ciKt.png" rel="nofollow noreferrer">Image 1: Actual result</a>
  The blue value is (for whatever reason) 25 in every pixel. The red and green areas reflect the x-y coordinates of the screen.</p>
  
  <p>Even if I rotate the camera a little bit, I get the exact same shading at the same screen coordinates:
  <img src="https://i.stack.imgur.com/nsz0e.png" alt="Image 2: Actual result with rotated camera"></p>
  
  <p>That shows me that the computed "worldPos" coordinates are screen coordinates and have nothing to do with the world coordinates of the plane.</p>
  
  <h2>Expected Result</h2>
  
  <p>The result I expect to see is the following:</p>
  
  <p><img src="https://i.stack.imgur.com/3mbHC.png" alt="Image 3: Expected result"></p>
  
  <p>Here, pixels that have the same (radial) distance to the camera have the same color.</p>
  
  <p>How do I need to change the above code to achieve this effect? With rayDir (computed in the vert function) I tried to get at least the direction vector from the camera center to the current pixel, such that I could compute the radial distance using the depth information. But rayDir has a constant value for all pixels ...</p>
  
  <p>At this point I also have to say that I don't really understand what is computed inside the vert function. This is just stuff that I found on the internet and that I tried out.</p>