Shader "Custom/Blur" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Color ("Tint", Color) = (1,1,1,0.2) _BlurSize ("Blur Size", Float) = 5 _BlurQuality ("Blur Quality", Float ) = 5 _BlurStrength ("Blur Strength", Float) = 1.2 // 新增:FairyGUI的Stencil属性(模板测试用) _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 // 新增:FairyGUI的颜色遮罩和混合模式属性 _ColorMask ("Color Mask", Float) = 15 _BlendSrcFactor ("Blend SrcFactor", Float) = 5 _BlendDstFactor ("Blend DstFactor", Float) = 10 } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" } // 新增:Stencil模板测试(关键,实现列表边框遮罩) Stencil { Ref [_Stencil] Comp [_StencilComp] Pass [_StencilOp] ReadMask [_StencilReadMask] WriteMask [_StencilWriteMask] } // 统一FairyGUI的渲染状态 Cull Off Lighting Off ZWrite Off Fog { Mode Off } Blend [_BlendSrcFactor] [_BlendDstFactor], One One // 替换原有Blend ColorMask [_ColorMask] // 新增颜色遮罩 Pass { CGPROGRAM #pragma multi_compile NOT_CLIPPED CLIPPED SOFT_CLIPPED ALPHA_MASK // 新增:FairyGUI裁剪宏 #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; float4 _MainTex_TexelSize; fixed4 _Color; float _BlurSize; int _BlurQuality; float _BlurStrength; // 新增:FairyGUI裁剪参数(和Image shader一致) #ifdef CLIPPED float4 _ClipBox = float4(-2, -2, 0, 0); // 裁剪区域 #endif #ifdef SOFT_CLIPPED float4 _ClipBox = float4(-2, -2, 0, 0); // 软裁剪区域 float4 _ClipSoftness = float4(0, 0, 0, 0); // 软裁剪过渡 #endif struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; // 新增:裁剪坐标(用于FairyGUI裁剪计算) #ifdef CLIPPED float2 clipPos : TEXCOORD1; #endif #ifdef SOFT_CLIPPED float2 clipPos : TEXCOORD1; #endif }; v2f vert(appdata_t IN) { v2f OUT; OUT.vertex = UnityObjectToClipPos(IN.vertex); OUT.texcoord = IN.texcoord; // 新增:颜色空间转换(和FairyGUI保持一致) #if !defined(UNITY_COLORSPACE_GAMMA) && (UNITY_VERSION >= 550) OUT.color.rgb = GammaToLinearSpace(IN.color.rgb) * _Color.rgb; OUT.color.a = IN.color.a * _Color.a; #else OUT.color = IN.color * _Color; #endif // 新增:计算裁剪坐标(FairyGUI裁剪逻辑) #ifdef CLIPPED OUT.clipPos = mul(unity_ObjectToWorld, IN.vertex).xy * _ClipBox.zw + _ClipBox.xy; #endif #ifdef SOFT_CLIPPED OUT.clipPos = mul(unity_ObjectToWorld, IN.vertex).xy * _ClipBox.zw + _ClipBox.xy; #endif return OUT; } // 高斯模糊权重计算(保留原有功能) float GaussianWeight(int x, int y, float sigma) { return exp(-(x*x + y*y) / (2.0 * sigma * sigma)) / (2.0 * 3.14159 * sigma * sigma); } fixed4 frag(v2f IN) : SV_Target { float2 uv = IN.texcoord; fixed4 col = fixed4(0,0,0,0); // 高斯模糊计算(保留) float totalWeight = 0.0; float sigma = _BlurQuality * _BlurStrength; int range = _BlurQuality * 2; for (int x = -range; x <= range; x++) { for (int y = -range; y <= range; y++) { float weight = GaussianWeight(x, y, sigma); totalWeight += weight; float2 offset = float2(x, y) * _BlurSize * _MainTex_TexelSize.xy; col += tex2D(_MainTex, uv + offset) * weight; } } col /= totalWeight; // 新增:FairyGUI裁剪逻辑(关键,适配列表边框裁剪) #ifdef CLIPPED float2 factor = abs(IN.clipPos); if (max(factor.x, factor.y) > 1) col.a = 0; // 硬裁剪 #endif #ifdef SOFT_CLIPPED float2 factor = float2(0,0); if (IN.clipPos.x < 0) factor.x = (1.0 - abs(IN.clipPos.x)) * _ClipSoftness.x; else factor.x = (1.0 - IN.clipPos.x) * _ClipSoftness.z; if (IN.clipPos.y < 0) factor.y = (1.0 - abs(IN.clipPos.y)) * _ClipSoftness.w; else factor.y = (1.0 - IN.clipPos.y) * _ClipSoftness.y; col.a *= clamp(min(factor.x, factor.y), 0.0, 1.0); // 软裁剪 #endif #ifdef ALPHA_MASK clip(col.a - 0.001); // 透明通道裁剪 #endif // 应用颜色 tint(和FairyGUI颜色处理保持一致) col.rgb *= IN.color.rgb; return col; } ENDCG } } }