Shader "Hidden/OutlinePlus" { Properties { [HideInInspector]_MainTex ("Texture", 2D) = "white" { } } SubShader { Cull Off ZWrite Off ZTest Always Fog { Mode Off } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #pragma shader_feature OUTLINE_USE_DEPTH #pragma shader_feature OUTLINE_USE_NORMALS sampler2D _MainTex; uniform float4 _MainTex_TexelSize; UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture); uniform sampler2D_float _CameraDepthNormalsTexture; uniform half _Thickness; uniform half4 _EdgeColor; uniform half2 _DepthThresholds; uniform half2 _NormalsThresholds; struct v2f { float2 uv: TEXCOORD0; float4 vertex: SV_POSITION; float2 depth_uv: TEXCOORD1; float3 screen_pos: TEXCOORD2; }; v2f vert(appdata_img v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.screen_pos = ComputeScreenPos(o.vertex); o.uv = v.texcoord; o.depth_uv = v.texcoord; return o; } fixed4 frag(v2f i): SV_Target { fixed4 original = tex2D(_MainTex, i.uv); float offset_positive = +ceil(_Thickness * 0.5); float offset_negative = -floor(_Thickness * 0.5); float left = _MainTex_TexelSize.x * offset_negative; float right = _MainTex_TexelSize.x * offset_positive; float top = _MainTex_TexelSize.y * offset_negative; float bottom = _MainTex_TexelSize.y * offset_positive; float2 uv0 = i.uv + float2(left, top); float2 uv1 = i.uv + float2(right, bottom); float2 uv2 = i.uv + float2(right, top); float2 uv3 = i.uv + float2(left, bottom); #ifdef OUTLINE_USE_DEPTH float d0 = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv0); float d1 = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv1); float d2 = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv2); float d3 = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv3); d0 = lerp(Linear01Depth(d0), d0, unity_OrthoParams.w); d1 = lerp(Linear01Depth(d1), d1, unity_OrthoParams.w); d2 = lerp(Linear01Depth(d2), d2, unity_OrthoParams.w); d3 = lerp(Linear01Depth(d3), d3, unity_OrthoParams.w); float d = length(float2(d1 - d0, d3 - d2)); d = smoothstep(_DepthThresholds.x, _DepthThresholds.y, d); #else float d = 0; #endif // OUTLINE_USE_DEPTH #ifdef OUTLINE_USE_NORMALS float3 n0, n1, n2, n3; float depth_ignore; DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, uv0), depth_ignore, n0); DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, uv1), depth_ignore, n1); DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, uv2), depth_ignore, n2); DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, uv3), depth_ignore, n3); float3 nd1 = n1 - n0; float3 nd2 = n3 - n2; float n = sqrt(dot(nd1, nd1) + dot(nd2, nd2)); n = smoothstep(_NormalsThresholds.x, _NormalsThresholds.y, n); #else float n = 0; #endif // OUTLINE_USE_NORMALS half g = max(d, n); half3 output = lerp(original.rgb, _EdgeColor.rgb, g * _EdgeColor.a); return half4(output, original.a); } ENDCG } } }