89 lines
3.3 KiB
HLSL
89 lines
3.3 KiB
HLSL
|
#ifndef PWAVE_INCLUDED
|
||
|
#define PWAVE_INCLUDED
|
||
|
|
||
|
#include "PUniforms.cginc"
|
||
|
#include "PCommon.cginc"
|
||
|
|
||
|
float2 SampleSpline(float t, float2 anchor0, float2 anchor1, float2 tangent0, float2 tangent1)
|
||
|
{
|
||
|
float oneMinusT = 1 - t;
|
||
|
float2 p = oneMinusT * oneMinusT * oneMinusT * anchor0 +
|
||
|
3 * oneMinusT * oneMinusT * t * tangent0 +
|
||
|
3 * oneMinusT * t * t * tangent1 +
|
||
|
t * t * t * anchor1;
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
half2 SampleWaveCurve(float t, half waveSteepness)
|
||
|
{
|
||
|
half2 left = half2(0, 0);
|
||
|
half2 right = half2(1, 0);
|
||
|
half2 middle = half2(lerp(0.5, 0.95, waveSteepness), 1);
|
||
|
|
||
|
half2 anchor0 = left * (t < middle.x) + middle * (t >= middle.x);
|
||
|
half2 anchor1 = middle * (t < middle.x) + right * (t >= middle.x);
|
||
|
half tangentLength = 0.5;
|
||
|
half2 tangent0 = float2(tangentLength, 0) * (t < middle.x) + float2(middle.x + tangentLength, middle.y) * (t >= middle.x);
|
||
|
half2 tangent1 = float2(middle.x - tangentLength, middle.y) * (t < middle.x) + float2(1 - tangentLength, 0) * (t >= middle.x);
|
||
|
half splineT = InverseLerpUnclamped(anchor0.x, anchor1.x, t);
|
||
|
|
||
|
half2 p = SampleSpline(splineT, anchor0, anchor1, tangent0, tangent1);
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
float4 CalculateWaveOffsetHQ(float4 vertex, float2 waveDirection, inout float crestMask)
|
||
|
{
|
||
|
float4 worldPos = mul(unity_ObjectToWorld, float4(vertex.xyz, 1));
|
||
|
#if WAVE_MASK
|
||
|
float maskU = InverseLerpUnclamped(_WaveMaskBounds.x, _WaveMaskBounds.z, worldPos.x);
|
||
|
float maskV = InverseLerpUnclamped(_WaveMaskBounds.y, _WaveMaskBounds.w, worldPos.z);
|
||
|
float4 mask = tex2Dlod(_WaveMask, float4(maskU, maskV, 0, 0));
|
||
|
float inbounds = (maskU >= 0) * (maskU <= 1) * (maskV >= 0) * (maskV <= 1);
|
||
|
|
||
|
//waveDirection = lerp(waveDirection, float2(mask.r * 2 - 1, mask.g * 2 - 1), inbounds);
|
||
|
#endif
|
||
|
|
||
|
half2 noisePos = worldPos.xz - 2 * _WaveSpeed * waveDirection * _PoseidonTime;
|
||
|
half noise = SampleVertexNoise(noisePos * 0.001) * _WaveDeform;
|
||
|
|
||
|
half dotValue = dot(worldPos.xz, waveDirection);
|
||
|
half t = frac((dotValue - _WaveSpeed * _PoseidonTime) / _WaveLength - noise * _WaveDeform * 0.25);
|
||
|
|
||
|
half2 p = SampleWaveCurve(t, _WaveSteepness);
|
||
|
p.y -= lerp(0.5, 1, noise * 0.5 + 0.5);
|
||
|
crestMask = saturate(p.y / _WaveHeight);
|
||
|
float4 offset = float4(0, _WaveHeight * p.y, 0, 0);
|
||
|
|
||
|
#if WAVE_MASK
|
||
|
float heightMask = lerp(1, mask.a, inbounds);
|
||
|
offset.y *= heightMask;
|
||
|
float crestMaskMask = lerp(1, mask.b, inbounds);
|
||
|
crestMask *= crestMaskMask;
|
||
|
#endif
|
||
|
|
||
|
return offset;
|
||
|
}
|
||
|
|
||
|
void ApplyWaveHQ(inout float4 v0, inout float4 v1, inout float4 v2, inout float crestMask)
|
||
|
{
|
||
|
float4 offset0 = CalculateWaveOffsetHQ(v0, _WaveDirection, crestMask);
|
||
|
v0 += offset0;
|
||
|
float tmp;
|
||
|
v1 += CalculateWaveOffsetHQ(v1, _WaveDirection, tmp);
|
||
|
v2 += CalculateWaveOffsetHQ(v2, _WaveDirection, tmp);
|
||
|
}
|
||
|
|
||
|
void ApplyWaveHQ(inout float4 vertex, inout float4 texcoord, inout float4 color, float4 texcoord1, inout float crestMask)
|
||
|
{
|
||
|
float2 flow0 = mul(unity_ObjectToWorld, float4(texcoord.w, 0, color.w, 0)).xz;
|
||
|
float2 flow1 = mul(unity_ObjectToWorld, float4(texcoord1.x, 0, texcoord1.y, 0)).xz;
|
||
|
float2 flow2 = mul(unity_ObjectToWorld, float4(texcoord1.z, 0, texcoord1.w, 0)).xz;
|
||
|
|
||
|
float4 offset0 = CalculateWaveOffsetHQ(vertex, flow0, crestMask);
|
||
|
vertex += offset0;
|
||
|
float tmp;
|
||
|
texcoord += CalculateWaveOffsetHQ(texcoord, flow1, tmp);
|
||
|
color += CalculateWaveOffsetHQ(color, flow2, tmp);
|
||
|
}
|
||
|
#endif
|