Files
KopMap/Assets/FlatKit/[Render Pipeline] Built-in/ImageEffects/Resources/OutlinePlus.shader
2025-09-02 18:55:19 +08:00

111 lines
3.1 KiB
Plaintext

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
}
}
}