#ifndef _FOURIER_WATER_INC #define _FOURIER_WATER_INC // Shared displacement derivatives for the surface normal and foam Jacobian. struct FourierWaterData { float dxx; float2 derivatives; // dxy, dyy }; FourierWaterData sample_fourier_water_data(float2 uv) { FourierWaterData data = (FourierWaterData) 0; #if defined(_FOURIER_WATER) data.dxx = _Fourier_Water_Height.SampleLevel(bilinear_repeat_s, uv, 0).b * -1; data.derivatives = _Fourier_Water_Displacement_Derivatives.SampleLevel( bilinear_repeat_s, uv, 0).rb * -1; #endif return data; } void fourier_water_deform(float2 uv, inout float3 objPos) { #if defined(_FOURIER_WATER) float h = _Fourier_Water_Height.SampleLevel(bilinear_repeat_s, uv, 0).r * -1; float scale = _Fourier_Water_Mesh_Size / _Fourier_Water_Patch_Size; float2 displacement = _Fourier_Water_Displacement.SampleLevel( bilinear_repeat_s, uv, 0).rb * -1; objPos.xy += displacement * scale * _Fourier_Water_Chop; objPos.z = -h * scale; #endif } void fourier_water_normals(float2 uv, FourierWaterData water, inout float3 normal, inout float3 tangent) { #if defined(_FOURIER_WATER) float4 data = _Fourier_Water_Normals.SampleLevel(bilinear_repeat_s, uv, 0); float2 slopes = data.rb * -1; float chop = _Fourier_Water_Chop; // UV 0..1 spans object-space XY; the original normal points along -Z. float3 tx = float3(1.0 + chop * water.dxx, chop * water.derivatives.x, -slopes.x); float3 ty = float3(chop * water.derivatives.x, 1.0 + chop * water.derivatives.y, -slopes.y); normal = normalize(cross(ty, tx)); tangent = normalize(tx); #endif } float fourier_water_foam(FourierWaterData water) { #if defined(_FOURIER_WATER) float chop = _Fourier_Water_Chop; float dxy = chop * water.derivatives.x; float J = (1.0 + chop * water.dxx) * (1.0 + chop * water.derivatives.y) - dxy * dxy; return 1.0 - smoothstep(_Fourier_Water_Foam_Full, _Fourier_Water_Foam_Start, J); #else return 0; #endif } #endif // _FOURIER_WATER_INC