Shader "GameFramework/UI/WaterRippleFade" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Color ("Tint", Color) = (1,1,1,1) _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 // ---- 水波纹参数 ---- _RippleAmplitude ("Ripple Amplitude", Range(0, 0.15)) = 0.02 _RippleFrequency ("Ripple Frequency", Range(1, 30)) = 8 _RippleSpeed ("Ripple Speed", Range(0, 10)) = 3 _RippleIntensity ("Ripple Intensity", Range(0, 1)) = 1 _FadeAlpha ("Fade Alpha", Range(0, 1)) = 1 } SubShader { Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "RenderPipeline" = "UniversalPipeline" "PreviewType" = "Plane" "CanUseSpriteAtlas" = "True" } Stencil { Ref [_Stencil] Comp [_StencilComp] Pass [_StencilOp] ReadMask [_StencilReadMask] WriteMask [_StencilWriteMask] } Cull Off Lighting Off ZWrite Off ZTest [unity_GUIZTestMode] Blend SrcAlpha OneMinusSrcAlpha ColorMask [_ColorMask] Pass { Name "Default" HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #pragma multi_compile_local _ UNITY_UI_CLIP_RECT #pragma multi_compile_local _ UNITY_UI_ALPHACLIP TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); float4 _MainTex_ST; CBUFFER_START(UnityPerMaterial) float4 _Color; float4 _ClipRect; float _RippleAmplitude; float _RippleFrequency; float _RippleSpeed; float _RippleIntensity; float _FadeAlpha; CBUFFER_END struct Attributes { float4 positionOS : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float4 positionCS : SV_POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; float4 worldPosition : TEXCOORD1; UNITY_VERTEX_OUTPUT_STEREO }; // UI 裁剪函数(兼容内置 UI 系统) float4 UnityGet2DClipping(float2 position, float4 clipRect) { float2 inside = step(clipRect.xy, position.xy) * step(position.xy, clipRect.zw); return float4(inside.x * inside.y, inside.x * inside.y, inside.x * inside.y, inside.x * inside.y); } Varyings vert(Attributes input) { Varyings output; UNITY_SETUP_INSTANCE_ID(input); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); output.worldPosition = input.positionOS; output.positionCS = TransformObjectToHClip(input.positionOS.xyz); output.texcoord = TRANSFORM_TEX(input.texcoord, _MainTex); output.color = input.color * _Color; return output; } half4 frag(Varyings input) : SV_Target { // ---- 水波纹 UV 扭曲 ---- float2 uv = input.texcoord; float time = _Time.y * _RippleSpeed; float amp = _RippleAmplitude * _RippleIntensity; // 三层正弦波叠加,模拟水面扰动 float wave1 = sin(uv.y * _RippleFrequency * 6.28 + time) * amp; float wave2 = sin(uv.x * _RippleFrequency * 4.5 + time * 1.3) * amp * 0.6; float wave3 = sin((uv.x + uv.y) * _RippleFrequency * 8.0 - time * 0.7) * amp * 0.3; uv.x += wave1 + wave3; uv.y += wave2 + wave3 * 0.5; // 采样纹理 half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv) * input.color; // ---- 渐现 Alpha ---- color.a *= _FadeAlpha; // UI 裁剪 #ifdef UNITY_UI_CLIP_RECT color.a *= UnityGet2DClipping(input.worldPosition.xy, _ClipRect).r; #endif #ifdef UNITY_UI_ALPHACLIP clip(color.a - 0.001); #endif return color; } ENDHLSL } } }