219 lines
7.4 KiB
Plaintext
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
|
|
}
|
|
}
|
|
} |