Files
test/Assets/ModelRenderer/Art/Shaders/Water/ClearWaterShader.shader
T
2026-01-13 09:45:32 +07:00

219 lines
7.4 KiB
Plaintext

Shader "Custom/WaterWithShore_Unity6"
{
Properties
{
_ShallowColor ("Shallow Color", Color) = (0.2, 0.6, 0.7, 0.8)
_DeepColor ("Deep Color", Color) = (0.0, 0.15, 0.25, 0.9)
_DepthMax ("Depth Max", Range(0.1, 10)) = 3
_WaveNormal ("Wave Normal", 2D) = "bump" {}
_NormalStrength ("Normal Strength", Range(0,2)) = 1
_WaveSpeed1 ("Wave Speed 1", Vector) = (0.05, 0.03, 0, 0)
_WaveSpeed2 ("Wave Speed 2", Vector) = (-0.03, 0.04, 0, 0)
_FoamNoise ("Foam Noise", 2D) = "white" {}
_FoamColor ("Foam Color", Color) = (1,1,1,1)
_FoamIntensity ("Foam Intensity", Range(0,2)) = 1
_FoamDepth ("Foam Depth", Range(0.01, 5)) = 0.6
_FoamNoiseScale ("Foam Noise Scale", Range(0.1, 5)) = 1
_FoamSpeed ("Foam Speed", Vector) = (0.1, 0.1, 0, 0)
_Smoothness ("Smoothness", Range(0,1)) = 0.85
[Header(Wave Animation)]
_WaveHeight ("Wave Height", Range(0, 1)) = 0.1
_WaveFrequency ("Wave Frequency", Range(0, 20)) = 5
_WaveSpeed ("Wave Speed", Range(0, 10)) = 2
_WaveDirection ("Wave Direction", Vector) = (1, 1, 0, 0)
}
SubShader
{
Tags
{
"RenderPipeline"="UniversalPipeline"
"Queue"="Transparent"
"RenderType"="Transparent"
}
Pass
{
Name "ForwardLit"
Tags { "LightMode"="UniversalForward" }
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#pragma prefer_hlslcc gles
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
TEXTURE2D(_WaveNormal);
SAMPLER(sampler_WaveNormal);
TEXTURE2D(_FoamNoise);
SAMPLER(sampler_FoamNoise);
TEXTURE2D_X_FLOAT(_CameraDepthTexture);
SAMPLER(sampler_CameraDepthTexture);
CBUFFER_START(UnityPerMaterial)
float4 _ShallowColor;
float4 _DeepColor;
float _DepthMax;
float4 _WaveSpeed1;
float4 _WaveSpeed2;
float _NormalStrength;
float4 _FoamColor;
float _FoamIntensity;
float _FoamDepth;
float _FoamNoiseScale;
float4 _FoamSpeed;
float _Smoothness;
float _WaveHeight;
float _WaveFrequency;
float _WaveSpeed;
float4 _WaveDirection;
CBUFFER_END
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
float4 screenPos : TEXCOORD1;
float3 positionWS : TEXCOORD2;
float3 normalWS : TEXCOORD3;
};
Varyings vert (Attributes v)
{
Varyings o;
// Transform to world space first
float3 worldPos = TransformObjectToWorld(v.positionOS.xyz);
// === WAVE ANIMATION ===
float2 waveDir = normalize(_WaveDirection.xy);
// Primary wave (moving wave)
float wave1 = sin(
dot(worldPos.xz, waveDir) * _WaveFrequency -
_Time.y * _WaveSpeed
) * _WaveHeight;
// Secondary wave (perpendicular, different frequency)
float2 waveDir2 = float2(-waveDir.y, waveDir.x); // Perpendicular
float wave2 = sin(
dot(worldPos.xz, waveDir2) * _WaveFrequency * 0.7 -
_Time.y * _WaveSpeed * 0.8
) * _WaveHeight * 0.5;
// Combine waves
worldPos.y += wave1 + wave2;
o.positionWS = worldPos;
o.positionCS = TransformWorldToHClip(worldPos);
o.screenPos = ComputeScreenPos(o.positionCS);
o.uv = v.uv;
o.normalWS = TransformObjectToWorldNormal(float3(0,1,0));
return o;
}
half4 frag (Varyings input) : SV_Target
{
// === NORMAL WAVES ===
float2 uv1 = input.uv + _Time.y * _WaveSpeed1.xy;
float2 uv2 = input.uv + _Time.y * _WaveSpeed2.xy;
float3 n1 = UnpackNormal(SAMPLE_TEXTURE2D(_WaveNormal, sampler_WaveNormal, uv1));
float3 n2 = UnpackNormal(SAMPLE_TEXTURE2D(_WaveNormal, sampler_WaveNormal, uv2));
float3 normalTS = n1 + n2;
normalTS.xy *= _NormalStrength;
normalTS = normalize(normalTS);
float3 normalWS = normalize(TransformTangentToWorld(
normalTS,
half3x3(
float3(1,0,0),
float3(0,0,1),
input.normalWS
)
));
// === DEPTH ===
float2 screenUV = input.screenPos.xy / input.screenPos.w;
float rawDepth = SAMPLE_TEXTURE2D_X(
_CameraDepthTexture,
sampler_CameraDepthTexture,
screenUV
).r;
float sceneDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
float waterDepth = LinearEyeDepth(
input.screenPos.z / input.screenPos.w,
_ZBufferParams
);
float depthDiff = sceneDepth - waterDepth;
// === DEPTH COLOR BLEND ===
float depth01 = saturate(depthDiff / _DepthMax);
float3 waterColor = lerp(
_ShallowColor.rgb,
_DeepColor.rgb,
depth01
);
// === SHORE FOAM ===
float shoreMask = saturate(1.0 - depthDiff / _FoamDepth);
float2 foamUV =
input.positionWS.xz * _FoamNoiseScale +
_Time.y * _FoamSpeed.xy;
float foamNoise = SAMPLE_TEXTURE2D(
_FoamNoise,
sampler_FoamNoise,
foamUV
).r;
float foam = shoreMask * foamNoise * _FoamIntensity;
// === LIGHTING ===
Light mainLight = GetMainLight();
float NdotL = saturate(dot(normalWS, mainLight.direction));
float3 finalColor =
waterColor * NdotL +
foam * _FoamColor.rgb;
float alpha = lerp(
_ShallowColor.a,
_DeepColor.a,
depth01
);
return float4(finalColor, alpha);
}
ENDHLSL
}
}
}