111 lines
3.1 KiB
Plaintext
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
|
|
|
|
}
|
|
}
|
|
}
|