Files
gold_dolphin/unity/Assets/Light/shaders/WaterReflection.shader
T
2026-07-04 16:26:44 +08:00

192 lines
7.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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"
}
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
Cull Off
Pass
{
Name "WaterReflection"
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
#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
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;
return finalColor;
}
ENDHLSL
}
}
FallBack Off
}