215 lines
8.0 KiB
Plaintext
215 lines
8.0 KiB
Plaintext
Shader "IndianOcean/WaterReflection"
|
||
{
|
||
// 水面倒影 Shader
|
||
// 上方 (1-R) 正常显示原图,下方 R 区域为原图整体垂直翻转 + 扰动 + 淡出,
|
||
// 分界线处绘制一条水面亮线。
|
||
|
||
Properties
|
||
{
|
||
_MainTex ("主贴图", 2D) = "white" {}
|
||
_Waterline ("水面线位置(UV.y)", Range(0.05, 0.95)) = 0.7
|
||
_DistortStrength("水平扰动强度", Range(0, 0.08)) = 0.015
|
||
_DistortSpeed ("扰动速度", Range(0, 5)) = 1.5
|
||
_DistortFreq ("扰动频率", Range(1, 20)) = 8.0
|
||
_ReflDarken ("倒影变暗系数", Range(0, 1)) = 0.5
|
||
_ReflFadeLen ("倒影向下淡出长度", Range(0, 0.5)) = 0.25
|
||
_LineBrightness ("水面线亮度", Range(0, 3)) = 1.5
|
||
_LineThickness ("水面线粗细", Range(0, 0.02)) = 0.004
|
||
_WaveAmplitude ("水面线波浪振幅", Range(0, 0.05)) = 0.012
|
||
_WaveFreq ("水面线波浪频率", Range(1, 15)) = 4.0
|
||
_WaveSpeed ("水面线波浪速度", Range(0, 5)) = 1.0
|
||
}
|
||
|
||
SubShader
|
||
{
|
||
Tags
|
||
{
|
||
"RenderType" = "Transparent"
|
||
"Queue" = "Transparent"
|
||
"RenderPipeline" = "UniversalPipeline"
|
||
"IgnoreProjector" = "True"
|
||
"CanUseSpriteAtlas" = "True"
|
||
}
|
||
Blend SrcAlpha OneMinusSrcAlpha
|
||
ZWrite Off
|
||
Cull Off
|
||
|
||
Pass
|
||
{
|
||
Name "WaterReflection"
|
||
HLSLPROGRAM
|
||
#pragma vertex vert
|
||
#pragma fragment frag
|
||
#pragma multi_compile_instancing
|
||
#pragma multi_compile __ UNITY_UI_CLIP_RECT
|
||
#pragma multi_compile __ UNITY_UI_ALPHACLIP
|
||
|
||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||
|
||
struct Attributes
|
||
{
|
||
float4 positionOS : POSITION;
|
||
float2 uv : TEXCOORD0;
|
||
float4 color : COLOR;
|
||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||
};
|
||
|
||
struct Varyings
|
||
{
|
||
float4 positionCS : SV_POSITION;
|
||
float2 uv : TEXCOORD0;
|
||
float4 color : COLOR;
|
||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||
};
|
||
|
||
CBUFFER_START(UnityPerMaterial)
|
||
float4 _MainTex_ST;
|
||
float _Waterline;
|
||
float _DistortStrength;
|
||
float _DistortSpeed;
|
||
float _DistortFreq;
|
||
float _ReflDarken;
|
||
float _ReflFadeLen;
|
||
float _LineBrightness;
|
||
float _LineThickness;
|
||
float _WaveAmplitude;
|
||
float _WaveFreq;
|
||
float _WaveSpeed;
|
||
CBUFFER_END
|
||
|
||
// UI ClipRect
|
||
float4 _ClipRect;
|
||
|
||
TEXTURE2D(_MainTex);
|
||
SAMPLER(sampler_MainTex);
|
||
|
||
/* ---------- noise ---------- */
|
||
float hash(float n)
|
||
{
|
||
return frac(sin(n) * 43758.5453);
|
||
}
|
||
|
||
float noise1D(float x)
|
||
{
|
||
float i = floor(x);
|
||
float f = frac(x);
|
||
f = f * f * (3.0 - 2.0 * f);
|
||
return lerp(hash(i), hash(i + 1.0), f);
|
||
}
|
||
|
||
// 多层叠加 → 类随机水面波纹,返回 [-1, 1]
|
||
float waterNoise(float x, float t)
|
||
{
|
||
float n = 0.0;
|
||
n += noise1D(x * _DistortFreq + t * _DistortSpeed) * 0.50;
|
||
n += noise1D(x * _DistortFreq * 2.3 - t * _DistortSpeed * 1.7) * 0.25;
|
||
n += noise1D(x * _DistortFreq * 4.7 + t * _DistortSpeed * 0.8) * 0.125;
|
||
return n * 2.0 - 1.0;
|
||
}
|
||
|
||
// 计算某 uv.x 处的局部水面线 Y 坐标(波浪起伏)
|
||
// 多层正弦叠加 + noise,产生自然的不规则波形
|
||
float localWaterline(float x, float t)
|
||
{
|
||
float wave = 0.0;
|
||
wave += sin(x * _WaveFreq * 6.2832 + t * _WaveSpeed) * 0.50;
|
||
wave += sin(x * _WaveFreq * 6.2832 * 2.3 - t * _WaveSpeed * 1.4) * 0.25;
|
||
wave += sin(x * _WaveFreq * 6.2832 * 4.1 + t * _WaveSpeed * 0.7) * 0.15;
|
||
wave += noise1D(x * _WaveFreq * 3.0 + t * _WaveSpeed * 0.5) * 0.10;
|
||
return _Waterline + wave * _WaveAmplitude;
|
||
}
|
||
|
||
Varyings vert(Attributes input)
|
||
{
|
||
Varyings output;
|
||
UNITY_SETUP_INSTANCE_ID(input);
|
||
UNITY_TRANSFER_INSTANCE_ID(input, output);
|
||
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
|
||
output.uv = TRANSFORM_TEX(input.uv, _MainTex);
|
||
output.color = input.color;
|
||
return output;
|
||
}
|
||
|
||
half4 frag(Varyings input) : SV_Target
|
||
{
|
||
float2 uv = input.uv;
|
||
float time = _Time.y;
|
||
|
||
// ========== 1. 原图采样(上方区域直接使用) ==========
|
||
half4 baseColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);
|
||
|
||
// ========== 2. 局部水面线(波浪起伏) ==========
|
||
float wl = localWaterline(uv.x, time);
|
||
|
||
// ========== 3. 判断是否在倒影区 ==========
|
||
float inRefl = 1.0 - step(wl, uv.y);
|
||
|
||
// ========== 4. 倒影 UV:整体垂直翻转 ==========
|
||
float2 reflUV = uv;
|
||
reflUV.y = 2.0 * wl - uv.y; // 以局部水面线为轴镜像
|
||
|
||
// 水平扰动
|
||
float distort = waterNoise(uv.x, time) * _DistortStrength;
|
||
// 越远离水面线(越往下)扰动越大
|
||
float depthRatio = 1.0 - uv.y / wl; // 0=水面, 1=最底
|
||
depthRatio = clamp(depthRatio, 0.0, 1.0);
|
||
distort *= (0.3 + 0.7 * depthRatio);
|
||
reflUV.x += distort;
|
||
|
||
// 夹紧,防止越界
|
||
reflUV = clamp(reflUV, 0.0, 1.0);
|
||
|
||
half4 reflColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, reflUV);
|
||
|
||
// ========== 5. 倒影衰减 ==========
|
||
// 5a. 整体变暗
|
||
reflColor.rgb *= (1.0 - _ReflDarken);
|
||
|
||
// 5b. 从水面线往下逐渐淡出(消散)
|
||
float fadeStart = wl - _ReflFadeLen;
|
||
float fadeFactor = smoothstep(fadeStart, wl, uv.y);
|
||
reflColor.a *= fadeFactor;
|
||
|
||
// ========== 6. 水面亮线(沿波浪曲线绘制) ==========
|
||
float distToLine = abs(uv.y - wl);
|
||
float lineFactor = 1.0 - smoothstep(0.0, _LineThickness, distToLine);
|
||
|
||
// ========== 7. 合成 ==========
|
||
half3 finalRGB = baseColor.rgb;
|
||
|
||
// 倒影区:用倒影色替换
|
||
finalRGB = lerp(finalRGB, reflColor.rgb, inRefl);
|
||
|
||
// 水面线:叠加高亮
|
||
finalRGB += lineFactor * _LineBrightness * half3(0.7, 0.85, 1.0);
|
||
|
||
float finalA = baseColor.a;
|
||
// 倒影区 alpha 也跟随淡出
|
||
finalA = lerp(finalA, reflColor.a, inRefl);
|
||
|
||
half4 finalColor = half4(finalRGB, finalA);
|
||
finalColor *= input.color;
|
||
|
||
// UI 裁剪矩形裁剪
|
||
#ifdef UNITY_UI_CLIP_RECT
|
||
float2 clipPos = input.positionCS.xy;
|
||
float clip = 1.0;
|
||
clip *= step(0.0, clipPos.x - _ClipRect.x);
|
||
clip *= step(0.0, clipPos.y - _ClipRect.y);
|
||
clip *= step(clipPos.x, _ClipRect.z);
|
||
clip *= step(clipPos.y, _ClipRect.w);
|
||
finalColor.a *= clip;
|
||
#endif
|
||
|
||
#ifdef UNITY_UI_ALPHACLIP
|
||
clip(finalColor.a - 0.001);
|
||
#endif
|
||
|
||
return finalColor;
|
||
}
|
||
ENDHLSL
|
||
}
|
||
}
|
||
FallBack Off
|
||
}
|