Shader "UI/Soft Shadow" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Color ("Tint", Color) = (1,1,1,1) _ShadowColor ("Shadow Color", Color) = (0,0,0,0.65) _ShadowOffset ("Shadow Offset (Pixels)", Vector) = (6,-6,0,0) _ShadowBlur ("Shadow Blur", Range(0,8)) = 2 _ShadowStrength ("Shadow Strength", Range(0,2)) = 1 _InsetPadding ("Extra Safe Inset", Range(0,0.25)) = 0.02 _StencilComp ("Stencil Comparison", Float) = 8 _Stencil ("Stencil ID", Float) = 0 _StencilOp ("Stencil Operation", Float) = 0 _StencilWriteMask ("Stencil Write Mask", Float) = 255 _StencilReadMask ("Stencil Read Mask", Float) = 255 _ColorMask ("Color Mask", Float) = 15 [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" } Stencil { Ref [_Stencil] ReadMask [_StencilReadMask] WriteMask [_StencilWriteMask] Comp [_StencilComp] Pass [_StencilOp] } Cull Off Lighting Off ZWrite Off ZTest [unity_GUIZTestMode] Blend One OneMinusSrcAlpha ColorMask [_ColorMask] Pass { Name "Default" HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #include "UnityCG.cginc" #include "UnityUI.cginc" #pragma multi_compile_local _ UNITY_UI_CLIP_RECT #pragma multi_compile_local _ UNITY_UI_ALPHACLIP struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; float4 worldPosition : TEXCOORD1; UNITY_VERTEX_OUTPUT_STEREO }; sampler2D _MainTex; float4 _MainTex_TexelSize; fixed4 _Color; fixed4 _TextureSampleAdd; float4 _ClipRect; fixed4 _ShadowColor; float4 _ShadowOffset; float _ShadowBlur; float _ShadowStrength; float _InsetPadding; v2f vert(appdata_t IN) { v2f OUT; UNITY_SETUP_INSTANCE_ID(IN); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); OUT.worldPosition = IN.vertex; OUT.vertex = UnityObjectToClipPos(OUT.worldPosition); OUT.texcoord = IN.texcoord; OUT.color = IN.color * _Color; return OUT; } float2 GetContentPad() { float2 autoPad = abs(_ShadowOffset.xy) * _MainTex_TexelSize.xy; autoPad += (_MainTex_TexelSize.xy * _ShadowBlur * 2.5); autoPad += _InsetPadding.xx; return clamp(autoPad, 0.0, 0.45); } float2 RemapUvToContent(float2 uv, float2 pad) { float2 denom = max(1e-5.xx, 1.0.xx - pad * 2.0); return (uv - pad) / denom; } fixed4 SampleSprite(float2 uv, fixed4 tint) { float inside = step(0.0, uv.x) * step(0.0, uv.y) * step(uv.x, 1.0) * step(uv.y, 1.0); if (inside < 0.5) { return 0; } fixed4 c = (tex2D(_MainTex, uv) + _TextureSampleAdd) * tint; c.rgb *= c.a; return c; } float SampleShadowAlpha(float2 uv, fixed alphaTint) { float2 offsetUv = uv + (_MainTex_TexelSize.xy * _ShadowOffset.xy); float2 blurUv = _MainTex_TexelSize.xy * _ShadowBlur; float a = 0.0; a += tex2D(_MainTex, offsetUv).a * 0.22702703; a += tex2D(_MainTex, offsetUv + float2( blurUv.x, 0)).a * 0.19459459; a += tex2D(_MainTex, offsetUv + float2(-blurUv.x, 0)).a * 0.19459459; a += tex2D(_MainTex, offsetUv + float2(0, blurUv.y)).a * 0.19459459; a += tex2D(_MainTex, offsetUv + float2(0, -blurUv.y)).a * 0.19459459; a += tex2D(_MainTex, offsetUv + float2( blurUv.x, blurUv.y)).a * 0.12162162; a += tex2D(_MainTex, offsetUv + float2(-blurUv.x, blurUv.y)).a * 0.12162162; a += tex2D(_MainTex, offsetUv + float2( blurUv.x, -blurUv.y)).a * 0.12162162; a += tex2D(_MainTex, offsetUv + float2(-blurUv.x, -blurUv.y)).a * 0.12162162; return saturate(a * alphaTint * _ShadowStrength); } fixed4 frag(v2f IN) : SV_Target { float2 pad = GetContentPad(); float2 contentUv = RemapUvToContent(IN.texcoord, pad); fixed4 src = SampleSprite(contentUv, IN.color); float shadowAlpha = SampleShadowAlpha(contentUv, IN.color.a) * _ShadowColor.a; ; fixed3 shadowRgb = _ShadowColor.rgb * shadowAlpha; fixed4 col; col.a = src.a + shadowAlpha * (1.0 - src.a); col.rgb = src.rgb + shadowRgb * (1.0 - src.a); #ifdef UNITY_UI_CLIP_RECT col *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); #endif #ifdef UNITY_UI_ALPHACLIP clip(col.a - 0.001); #endif return col; } ENDHLSL } } }