I did the following shader (looked up and changed for my needs):
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/DepthShader"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _CameraDepthTexture;
uniform half4 _CameraDepthTexture_TexelSize;
struct input
{
float4 pos : POSITION;
half2 uv : TEXCOORD0;
};
struct output
{
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
};
output vert(input i)
{
output o;
o.pos = UnityObjectToClipPos(i.pos);
o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, i.uv);
// why do we need this? cause sometimes the image I get is flipped. see: http://docs.unity3d.com/Manual/SL-PlatformDifferences.html
#if UNITY_UV_STARTS_AT_TOP
if (_CameraDepthTexture_TexelSize.y < 0)
o.uv.y = 1 - o.uv.y;
#endif
return o;
}
fixed4 frag(output o) : COLOR
{
float depth = DECODE_EYEDEPTH(tex2D(_CameraDepthTexture, o.uv));
return depth;
}
ENDCG
}
}
}
What i want is to get depth map with actual distances, not within 0-1 range. Main script is showing color scene but inside i'm checking what's the distance to center of screen:
private Shader _shader;
private Shader shader
{
get { return _shader != null ? _shader : (_shader = Shader.Find("Custom/DepthShader")); }
}
private Material _material;
private Material material
{
get
{
if (_material == null)
{
_material = new Material(shader);
_material.hideFlags = HideFlags.HideAndDontSave;
}
return _material;
}
}
private void Start()
{ GetComponent<Camera>().depthTextureMode = DepthTextureMode.Depth;
}
private void OnRenderImage(RenderTexture src, RenderTexture dest)
{
RenderTexture buffer = new RenderTexture(
Screen.width, Screen.height,
0, // No depth/stencil buffer
RenderTextureFormat.ARGBFloat, // Standard colour format
RenderTextureReadWrite.Linear // No sRGB conversions
);
Graphics.Blit(src, buffer, material);
// main scene
Graphics.Blit(src, dest);
RenderTexture.active = buffer; // If not using a scene camera
Texture2D outputTex = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBAFloat, false);
outputTex.ReadPixels(
new Rect(0, 0, Screen.width, Screen.height),
0, 0,
false
);
outputTex.Apply();
Color[] depthMap = outputTex.GetPixels();
Color color = depthMap[Screen.width * Screen.height / 2 + Screen.width / 2];
Debug.Log("distance to center pixel is: " + color[0]);
Object.Destroy(outputTex);
}
So here: Debug.Log("distance to center pixel is: " + color[0]); I'm trying to check correctness of my depth values by checking center pixel value. In the scene I put camera then after 25 meters small wall then again after 25 meters big wall (parallel to small one). So camera is looking at the center of small wall. I am expecting the center pixel to be the small wall so depth value should be ~25.
But what I get from Debug.Log is something around 999.8341. If camera is positioned closer i start seeing more or less reasonable values.
I decided saved those values into file as matrix and here is what it is showing around the center:

Is my approach correct or did I make some mistake?
