Shader "Mgin/DepthGrayscale" { Properties { _MainTex ("",2D) = "white" {} _Cutoff ("", Float) = 0.5 _Color ("", Color ) = (1,1,1,1) } Category { Fog { Mode Off } SubShader { Tags { "RenderType" = "Opaque" "DepthRender"="Opaque" } Pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" uniform half4 _MainTex_TexelSize; sampler2D _CameraDepthTexture; struct v2f { float4 pos : SV_POSITION; float4 scrPos:TEXCOORD1; }; // 0~1 범위의 screen 좌표값을 얻는다. inline float4 CustomScreenPos (float4 pos) { float4 o = pos; // 투영행렬에서 카메라 공간상에 존재하는 점과 카메라 위치 사이의 깊이값 z는 // 최종 결과점의 x,y,z에 각각 곱해지고, w에 저장된다. // 해당 좌표공간(카메라, 투영, 월드)에서 3d 좌표를 얻으려면 w로 나누면 된다. // x, y, z 값을 w로 나누어 w는 1이되게 하고 xyz는 -1~1의 범위를 갖게 한다. o.xy = (o.xy+_MainTex_TexelSize.xy) / o.w; o.xy = float2(o.x+1, o.y+1) * 0.5; // -1~1 범위를 0~1로 변경 return o; } // _ZBufferParams : x (1-far/near), y (far/near), z (x/far), w (y/far) // 깊이값을 표현하는 높은 정밀도의 float값 반환 //_CameraDepthTexture의 r에 깊이값을 저장하고 있다. // 카메라의 깊이 텍스쳐를 decode 하는 방법이 더 있긴 하지만 // 이 방법이 가장 실용적이다. inline float CustomLinear01Depth( float z ) { return 1.0 / (_ZBufferParams.x * z + _ZBufferParams.y); //return 1/ (z *(1- _ProjectionParams.z/_ProjectionParams.y) + _ProjectionParams.z/_ProjectionParams.y); } v2f vert (appdata_base v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex); o.scrPos= CustomScreenPos(o.pos); //o.scrPos= ComputeScreenPos(o.pos); //o.scrPos.xy = o.pos.xy * 0.5 + _ScreenParams.zw*0.5; #if UNITY_UV_STARTS_AT_TOP if( o.scrPos.y < 0.0 ) { o.scrPos.y = 1.0 - o.scrPos.y; } #endif return o; } //Fragment Shader half4 frag (v2f i) : COLOR { //Grab the depth value from the depth texture //Linear01Depth restricts this value to [0, 1] float depthValue = CustomLinear01Depth (tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.scrPos)).r); // UNITY_PROJ_COORD (a) - 4 개의 벡터 구성요소를 전달하면 // 투영된 텍스처 읽기에 적절한 텍스처 좌표를 리턴합니다. // 대부분의 플랫폼에서는 전달된 값 자체를 리턴합니다. //depthValue = CustomLinear01Depth(tex2Dproj(_CameraDepthTexture, i.scrPos)).r; //depthValue = Linear01Depth (tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.scrPos)).r); half4 depth; depth.r = depthValue; depth.g = depthValue; depth.b = depthValue; depth.a = 1; return depth; } //http://williamchyr.com/2013/11/unity-shaders-depth-and-normal-textures/ //http://raptusgames.com/youre-such-a-nerd-b-vol03/ //http://answers.unity3d.com/questions/877170/render-scene-depth-to-a-texture.html ENDCG } } } } // https://en.wikibooks.org/wiki/Cg_Programming/Unity/Shading_in_World_Space // https://github.com/robertcupisz/LightShafts/blob/master/Depth.shader // http://forum.unity3d.com/threads/_projectionparams-z-is-not-equal-to-camera-farclipplane.204592/