Shader "Hidden/Post FX/Builtin Debug Views" { CGINCLUDE #include "UnityCG.cginc" #include "Common.cginc" #pragma exclude_renderers d3d11_9x sampler2D_float _CameraDepthTexture; sampler2D_float _CameraDepthNormalsTexture; sampler2D_float _CameraMotionVectorsTexture; float4 _CameraDepthTexture_ST; float4 _CameraDepthNormalsTexture_ST; float4 _CameraMotionVectorsTexture_ST; #if SOURCE_GBUFFER sampler2D _CameraGBufferTexture2; float4 _CameraGBufferTexture2_ST; #endif // ----------------------------------------------------------------------------- // Depth float _DepthScale; float4 FragDepth(VaryingsDefault i) : SV_Target { float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv, _CameraDepthTexture_ST)); depth = Linear01Depth(depth) * _DepthScale; float3 d = depth.xxx; #if !UNITY_COLORSPACE_GAMMA d = GammaToLinearSpace(d); #endif return float4(d, 1.0); } // ----------------------------------------------------------------------------- // Normals float3 SampleNormal(float2 uv) { #if SOURCE_GBUFFER float3 norm = tex2D(_CameraGBufferTexture2, uv).xyz * 2.0 - 1.0; return mul((float3x3)unity_WorldToCamera, norm); #else float4 cdn = tex2D(_CameraDepthNormalsTexture, uv); return DecodeViewNormalStereo(cdn) * float3(1.0, 1.0, -1.0); #endif } float4 FragNormals(VaryingsDefault i) : SV_Target { float3 n = SampleNormal(UnityStereoScreenSpaceUVAdjust(i.uv, _CameraDepthNormalsTexture_ST)); #if UNITY_COLORSPACE_GAMMA n = LinearToGammaSpace(n); #endif return float4(n, 1.0); } // ----------------------------------------------------------------------------- // Motion vectors float _Opacity; float _Amplitude; float4 _Scale; float4 FragMovecsOpacity(VaryingsDefault i) : SV_Target { float4 src = tex2D(_MainTex, i.uv); return float4(src.rgb * _Opacity, src.a); } // Convert a motion vector into RGBA color. float4 VectorToColor(float2 mv) { float phi = atan2(mv.x, mv.y); float hue = (phi / UNITY_PI + 1.0) * 0.5; float r = abs(hue * 6.0 - 3.0) - 1.0; float g = 2.0 - abs(hue * 6.0 - 2.0); float b = 2.0 - abs(hue * 6.0 - 4.0); float a = length(mv); return saturate(float4(r, g, b, a)); } float4 FragMovecsImaging(VaryingsDefault i) : SV_Target { float4 src = tex2D(_MainTex, i.uv); float2 mv = tex2D(_CameraMotionVectorsTexture, i.uv).rg * _Amplitude; #if UNITY_UV_STARTS_AT_TOP mv.y *= -1.0; #endif float4 mc = VectorToColor(mv); float3 rgb = src.rgb; #if !UNITY_COLORSPACE_GAMMA rgb = LinearToGammaSpace(rgb); #endif rgb = lerp(rgb, mc.rgb, mc.a * _Opacity); #if !UNITY_COLORSPACE_GAMMA rgb = GammaToLinearSpace(rgb); #endif return float4(rgb, src.a); } struct VaryingsArrows { float4 vertex : SV_POSITION; float2 scoord : TEXCOORD; float4 color : COLOR; }; VaryingsArrows VertArrows(AttributesDefault v) { // Retrieve the motion vector. float4 uv = float4(v.texcoord.xy, 0.0, 0.0); #if UNITY_UV_STARTS_AT_TOP uv.y = 1.0 - uv.y; #endif float2 mv = tex2Dlod(_CameraMotionVectorsTexture, uv).rg * _Amplitude; #if UNITY_UV_STARTS_AT_TOP mv.y *= -1.0; #endif // Arrow color float4 color = VectorToColor(mv); // Make a rotation matrix based on the motion vector. float2x2 rot = float2x2(mv.y, mv.x, -mv.x, mv.y); // Rotate and scale the body of the arrow. float2 pos = mul(rot, v.vertex.zy) * _Scale.xy; // Normalized variant of the motion vector and the rotation matrix. float2 mv_n = normalize(mv); float2x2 rot_n = float2x2(mv_n.y, mv_n.x, -mv_n.x, mv_n.y); // Rotate and scale the head of the arrow. float2 head = float2(v.vertex.x, -abs(v.vertex.x)) * 0.3; head *= saturate(color.a); pos += mul(rot_n, head) * _Scale.xy; // Offset the arrow position. pos += v.texcoord.xy * 2.0 - 1.0; // Convert to the screen coordinates. float2 scoord = (pos + 1.0) * 0.5 * _ScreenParams.xy; // Snap to a pixel-perfect position. scoord = round(scoord); // Bring back to the normalized screen space. pos = (scoord + 0.5) * (_ScreenParams.zw - 1.0) * 2.0 - 1.0; // Color tweaks color.rgb = GammaToLinearSpace(lerp(color.rgb, 1.0, 0.5)); color.a *= _Opacity; // Output VaryingsArrows o; o.vertex = float4(pos, 0.0, 1.0); o.scoord = scoord; o.color = saturate(color); return o; } float4 FragMovecsArrows(VaryingsArrows i) : SV_Target { // Pseudo anti-aliasing. float aa = length(frac(i.scoord) - 0.5) / 0.707; aa *= (aa * (aa * 0.305306011 + 0.682171111) + 0.012522878); // gamma return float4(i.color.rgb, i.color.a * aa); } ENDCG SubShader { Cull Off ZWrite Off ZTest Always // (0) - Depth Pass { CGPROGRAM #pragma vertex VertDefault #pragma fragment FragDepth ENDCG } // (1) - Normals Pass { CGPROGRAM #pragma vertex VertDefault #pragma fragment FragNormals #pragma multi_compile __ SOURCE_GBUFFER ENDCG } // (2) - Motion vectors - Opacity Pass { CGPROGRAM #pragma vertex VertDefault #pragma fragment FragMovecsOpacity ENDCG } // (3) - Motion vectors - Imaging Pass { CGPROGRAM #pragma vertex VertDefault #pragma fragment FragMovecsImaging #pragma multi_compile __ UNITY_COLORSPACE_GAMMA ENDCG } // (4) - Motion vectors - Arrows Pass { Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex VertArrows #pragma fragment FragMovecsArrows ENDCG } } }