From f8cd841a9c83ae208d30160645f6ce73bc1d09f0 Mon Sep 17 00:00:00 2001 From: Dale Eidd Date: Mon, 13 Jan 2025 11:25:47 +1000 Subject: [PATCH] Fix #1156 Use infinity water depth Fixes incorrect depth values when away from zero, and simplifies a few things. Caution must be taken as infinity can cause issues. Water depth sampling had to be moved to the fragment shader, as it had artifacts from using infinity, possibly from interpolation. Additionally, needed to adjust values after sampling in fragment. --- .../LodData/LodDataMgrSeaFloorDepth.cs | 6 ++-- .../Crest/Scripts/LodData/OceanDepthCache.cs | 4 +-- .../Settings/SimSettingsAnimatedWaves.cs | 4 +-- crest/Assets/Crest/Crest/Shaders/Ocean.shader | 36 ++++++++++++++----- .../Crest/Crest/Shaders/OceanConstants.hlsl | 4 ++- .../Crest/Crest/Shaders/OceanHelpersNew.hlsl | 17 +++++---- .../OceanInputs/AnimWavesSpectrum.shader | 5 +-- .../Shaders/OceanInputs/GerstnerShared.hlsl | 3 +- .../Resources/AnimWavesGerstner.shader | 5 +-- .../AnimWavesGerstnerGeometry.shader | 5 +-- .../Shaders/Resources/UpdateDynWaves.compute | 3 +- .../Shaders/Resources/UpdateFoam.compute | 3 +- .../Underwater/UnderwaterCurtain.shader | 2 +- .../Underwater/UnderwaterEffectShared.hlsl | 2 +- 14 files changed, 63 insertions(+), 36 deletions(-) diff --git a/crest/Assets/Crest/Crest/Scripts/LodData/LodDataMgrSeaFloorDepth.cs b/crest/Assets/Crest/Crest/Scripts/LodData/LodDataMgrSeaFloorDepth.cs index d3fc56222..ce5bb4f50 100644 --- a/crest/Assets/Crest/Crest/Scripts/LodData/LodDataMgrSeaFloorDepth.cs +++ b/crest/Assets/Crest/Crest/Scripts/LodData/LodDataMgrSeaFloorDepth.cs @@ -17,13 +17,13 @@ namespace Crest public class LodDataMgrSeaFloorDepth : LodDataMgr { // NOTE: Must match CREST_OCEAN_DEPTH_BASELINE in OceanConstants.hlsl. - internal const float k_DepthBaseline = 1_000f; + internal const float k_DepthBaseline = Mathf.Infinity; public override string SimName => "SeaFloorDepth"; protected override GraphicsFormat RequestedTextureFormat => Settings._allowVaryingWaterLevel ? GraphicsFormat.R32G32_SFloat : GraphicsFormat.R16_SFloat; protected override bool NeedToReadWriteTextureData => false; - // We want the clear colour to be the min terrain height (-1000m) in X, and sea level offset 0m in Y. - readonly static Color s_nullColor = Color.red * -k_DepthBaseline; + // Lowest possible scene height in X, and sea level offset 0m in Y. + readonly static Color s_nullColor = new Color(-k_DepthBaseline, 0, 0, 0); static Texture2DArray s_nullTexture; protected override Texture2DArray NullTexture => s_nullTexture; diff --git a/crest/Assets/Crest/Crest/Scripts/LodData/OceanDepthCache.cs b/crest/Assets/Crest/Crest/Scripts/LodData/OceanDepthCache.cs index 9b47e4d0e..d528b3d53 100644 --- a/crest/Assets/Crest/Crest/Scripts/LodData/OceanDepthCache.cs +++ b/crest/Assets/Crest/Crest/Scripts/LodData/OceanDepthCache.cs @@ -218,9 +218,7 @@ bool InitObjects(bool updateComponents) _camDepthCache.transform.parent = transform; _camDepthCache.transform.localEulerAngles = 90f * Vector3.right; _camDepthCache.orthographic = true; - _camDepthCache.clearFlags = CameraClearFlags.SolidColor; - // Clear to 'very deep' - _camDepthCache.backgroundColor = Color.white * LodDataMgrSeaFloorDepth.k_DepthBaseline; + _camDepthCache.clearFlags = CameraClearFlags.Depth; _camDepthCache.enabled = false; _camDepthCache.allowMSAA = false; _camDepthCache.allowDynamicResolution = false; diff --git a/crest/Assets/Crest/Crest/Scripts/LodData/Settings/SimSettingsAnimatedWaves.cs b/crest/Assets/Crest/Crest/Scripts/LodData/Settings/SimSettingsAnimatedWaves.cs index eccf4fb18..c87376fab 100644 --- a/crest/Assets/Crest/Crest/Scripts/LodData/Settings/SimSettingsAnimatedWaves.cs +++ b/crest/Assets/Crest/Crest/Scripts/LodData/Settings/SimSettingsAnimatedWaves.cs @@ -35,8 +35,8 @@ public partial class SimSettingsAnimatedWaves : SimSettingsBase public float AttenuationInShallows => _attenuationInShallows; [Tooltip("Any water deeper than this will receive full wave strength. The lower the value, the less effective the depth cache will be at attenuating very large waves. Set to the maximum value (1,000) to disable.")] - [SerializeField, Range(1f, LodDataMgrSeaFloorDepth.k_DepthBaseline)] - float _shallowsMaxDepth = LodDataMgrSeaFloorDepth.k_DepthBaseline; + [SerializeField, Range(1f, 1000f)] + float _shallowsMaxDepth = 1000f; public float MaximumAttenuationDepth => _shallowsMaxDepth; public enum CollisionSources diff --git a/crest/Assets/Crest/Crest/Shaders/Ocean.shader b/crest/Assets/Crest/Crest/Shaders/Ocean.shader index 14de04d28..0571bd14f 100644 --- a/crest/Assets/Crest/Crest/Shaders/Ocean.shader +++ b/crest/Assets/Crest/Crest/Shaders/Ocean.shader @@ -364,7 +364,6 @@ Shader "Crest/Ocean" // sample shape textures - always lerp between 2 LOD scales, so sample two textures o.flow_shadow = half4(0.0, 0.0, 0.0, 0.0); - o.lodAlpha_worldXZUndisplaced_oceanDepth.w = CREST_OCEAN_DEPTH_BASELINE; // Sample shape textures - always lerp between 2 LOD scales, so sample two textures // Calculate sample weights. params.z allows shape to be faded out (used on last lod to support pop-less scale transitions) @@ -410,11 +409,12 @@ Shader "Crest/Ocean" // Data that needs to be sampled at the displaced position half seaLevelOffset = 0.0; o.seaLevelDerivs = 0.0; + half seaDepth = 0; if (wt_smallerLod > 0.0001) { const float3 uv_slice_smallerLodDisp = WorldToUV(o.worldPos.xz, cascadeData0, _LD_SliceIndex); - SampleSeaDepth(_LD_TexArray_SeaFloorDepth, uv_slice_smallerLodDisp, wt_smallerLod, o.lodAlpha_worldXZUndisplaced_oceanDepth.w, seaLevelOffset, cascadeData0, o.seaLevelDerivs); + SampleSeaDepth(_LD_TexArray_SeaFloorDepth, uv_slice_smallerLodDisp, wt_smallerLod, seaDepth, seaLevelOffset, cascadeData0, o.seaLevelDerivs); #if _SHADOWS_ON // The minimum sampling weight is lower than others to fix shallow water colour popping. @@ -428,7 +428,7 @@ Shader "Crest/Ocean" { const float3 uv_slice_biggerLodDisp = WorldToUV(o.worldPos.xz, cascadeData1, _LD_SliceIndex + 1); - SampleSeaDepth(_LD_TexArray_SeaFloorDepth, uv_slice_biggerLodDisp, wt_biggerLod, o.lodAlpha_worldXZUndisplaced_oceanDepth.w, seaLevelOffset, cascadeData1, o.seaLevelDerivs); + SampleSeaDepth(_LD_TexArray_SeaFloorDepth, uv_slice_biggerLodDisp, wt_biggerLod, seaDepth, seaLevelOffset, cascadeData1, o.seaLevelDerivs); #if _SHADOWS_ON // The minimum sampling weight is lower than others to fix shallow water colour popping. @@ -526,10 +526,6 @@ Shader "Crest/Ocean" half3 screenPos = input.screenPosXYW; half2 uvDepth = screenPos.xy / screenPos.z; - #if _CLIPUNDERTERRAIN_ON - clip(input.lodAlpha_worldXZUndisplaced_oceanDepth.w + 2.0); - #endif - half3 view = normalize(_WorldSpaceCameraPos - input.worldPos); // water surface depth, and underlying scene opaque surface depth @@ -563,6 +559,8 @@ Shader "Crest/Ocean" #if _ALBEDO_ON half4 albedo = 0.0; #endif + + float seaDepth = 0; if (wt_smallerLod > 0.001) { const float3 uv_slice_smallerLod = WorldToUV(positionXZWSUndisplaced, cascadeData0, _LD_SliceIndex); @@ -575,6 +573,10 @@ Shader "Crest/Ocean" #if _ALBEDO_ON SampleAlbedo(_LD_TexArray_Albedo, uv_slice_smallerLod, wt_smallerLod, albedo); #endif + + #if defined(_SUBSURFACESHALLOWCOLOUR_ON) || defined(_CLIPUNDERTERRAIN_ON) + SampleSeaDepth(_LD_TexArray_SeaFloorDepth, uv_slice_smallerLod, wt_smallerLod, seaDepth); + #endif } if (wt_biggerLod > 0.001) { @@ -588,8 +590,24 @@ Shader "Crest/Ocean" #if _ALBEDO_ON SampleAlbedo(_LD_TexArray_Albedo, uv_slice_biggerLod, wt_biggerLod, albedo); #endif + + #if defined(_SUBSURFACESHALLOWCOLOUR_ON) || defined(_CLIPUNDERTERRAIN_ON) + SampleSeaDepth(_LD_TexArray_SeaFloorDepth, uv_slice_biggerLod, wt_biggerLod, seaDepth); + #endif } +#if _SUBSURFACESHALLOWCOLOUR_ON + seaDepth = min(_SubSurfaceDepthMax, seaDepth); + if (_LD_SliceIndex == ((uint)_SliceCount - 1)) + { + seaDepth = lerp(_SubSurfaceDepthMax, seaDepth, wt_smallerLod); + } +#endif + + #if _CLIPUNDERTERRAIN_ON + clip(seaDepth + 2.0); + #endif + #if _SUBSURFACESCATTERING_ON // Extents need the default SSS to avoid popping and not being noticeably different. if (_LD_SliceIndex == ((uint)_SliceCount - 1)) @@ -668,7 +686,7 @@ Shader "Crest/Ocean" // Compute color of ocean - in-scattered light + refracted scene half3 scatterCol = ScatterColour ( - input.lodAlpha_worldXZUndisplaced_oceanDepth.w, + seaDepth, shadow.x, sss, view, @@ -752,7 +770,7 @@ Shader "Crest/Ocean" // global shadow value. scatterCol = ScatterColour ( - input.lodAlpha_worldXZUndisplaced_oceanDepth.w, + seaDepth, UnderwaterShadowSSS(_WorldSpaceCameraPos.xz), sss, view, diff --git a/crest/Assets/Crest/Crest/Shaders/OceanConstants.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanConstants.hlsl index 0148c9f96..1f511249c 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanConstants.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/OceanConstants.hlsl @@ -18,7 +18,9 @@ // NOTE: Must match k_DepthBaseline in LodDataMgrSeaFloorDepth.cs. // Bias ocean floor depth so that default (0) values in texture are not interpreted as shallow and generating foam everywhere -#define CREST_OCEAN_DEPTH_BASELINE 1000.0 +#define CREST_OCEAN_DEPTH_BASELINE asfloat(0x7F800000) +#define CREST_MAXIMUM_ATTENUATION_DEPTH 1000.0 +#define CREST_FLOAT_MAXIMUM 3.402823466e+38 // Soft shadows is red, hard shadows is green. #define CREST_SHADOW_INDEX_SOFT 0 diff --git a/crest/Assets/Crest/Crest/Shaders/OceanHelpersNew.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanHelpersNew.hlsl index 50d493f99..9faaa8191 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanHelpersNew.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/OceanHelpersNew.hlsl @@ -124,23 +124,25 @@ void SampleAlbedo(in Texture2DArray i_oceanAlbedoSampler, in float3 i_uv_slice, void SampleSeaDepth(in Texture2DArray i_oceanDepthSampler, in float3 i_uv_slice, in float i_wt, inout half io_oceanDepth) { - const half2 terrainHeight_seaLevelOffset = i_oceanDepthSampler.SampleLevel(LODData_linear_clamp_sampler, i_uv_slice.xyz, 0.0).xy; + half2 terrainHeight_seaLevelOffset = i_oceanDepthSampler.SampleLevel(LODData_linear_clamp_sampler, i_uv_slice.xyz, 0.0).xy; + terrainHeight_seaLevelOffset.x = max(terrainHeight_seaLevelOffset.x, -CREST_FLOAT_MAXIMUM); const half waterDepth = _OceanCenterPosWorld.y - terrainHeight_seaLevelOffset.x + terrainHeight_seaLevelOffset.y; - io_oceanDepth += i_wt * (waterDepth - CREST_OCEAN_DEPTH_BASELINE); + io_oceanDepth += i_wt * waterDepth; } void SampleSingleSeaDepth(Texture2DArray i_oceanDepthSampler, float3 i_uv_slice, inout half io_oceanDepth, inout half io_seaLevelOffset) { - const half2 terrainHeight_seaLevelOffset = i_oceanDepthSampler.SampleLevel(LODData_linear_clamp_sampler, i_uv_slice, 0.0).xy; - const half waterDepth = _OceanCenterPosWorld.y - terrainHeight_seaLevelOffset.x + terrainHeight_seaLevelOffset.y; - io_oceanDepth = waterDepth - CREST_OCEAN_DEPTH_BASELINE; + half2 terrainHeight_seaLevelOffset = i_oceanDepthSampler.SampleLevel(LODData_linear_clamp_sampler, i_uv_slice, 0.0).xy; + terrainHeight_seaLevelOffset.x = max(terrainHeight_seaLevelOffset.x, -CREST_FLOAT_MAXIMUM); + io_oceanDepth = _OceanCenterPosWorld.y - terrainHeight_seaLevelOffset.x + terrainHeight_seaLevelOffset.y; io_seaLevelOffset = terrainHeight_seaLevelOffset.y; } void SampleSeaDepth(in Texture2DArray i_oceanDepthSampler, in float3 i_uv_slice, in float i_wt, inout half io_oceanDepth, inout half io_seaLevelOffset, const CascadeParams i_cascadeParams, inout float2 io_seaLevelDerivs) { - const half2 terrainHeight_seaLevelOffset = i_oceanDepthSampler.SampleLevel( LODData_linear_clamp_sampler, i_uv_slice, 0.0 ).xy; - io_oceanDepth += i_wt * (_OceanCenterPosWorld.y - terrainHeight_seaLevelOffset.x + terrainHeight_seaLevelOffset.y - CREST_OCEAN_DEPTH_BASELINE); + half2 terrainHeight_seaLevelOffset = i_oceanDepthSampler.SampleLevel( LODData_linear_clamp_sampler, i_uv_slice, 0.0 ).xy; + terrainHeight_seaLevelOffset.x = max(terrainHeight_seaLevelOffset.x, -CREST_FLOAT_MAXIMUM); + io_oceanDepth += i_wt * (_OceanCenterPosWorld.y - terrainHeight_seaLevelOffset.x + terrainHeight_seaLevelOffset.y); io_seaLevelOffset += i_wt * terrainHeight_seaLevelOffset.y; { @@ -159,6 +161,7 @@ void SampleSeaDepth(in Texture2DArray i_oceanDepthSampler, in float3 i_uv_slice, void SampleTerrainHeight(const Texture2DArray i_texture, const float3 i_uv, inout half io_terrainHeight) { io_terrainHeight = i_texture.SampleLevel(LODData_linear_clamp_sampler, i_uv, 0.0).x; + io_terrainHeight = max(io_terrainHeight, -CREST_FLOAT_MAXIMUM); } void SampleSeaLevelOffset(in Texture2DArray i_oceanDepthSampler, in float3 i_uv_slice, in float i_wt, inout half io_seaLevelOffset) diff --git a/crest/Assets/Crest/Crest/Shaders/OceanInputs/AnimWavesSpectrum.shader b/crest/Assets/Crest/Crest/Shaders/OceanInputs/AnimWavesSpectrum.shader index 189797f53..dfda1e679 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanInputs/AnimWavesSpectrum.shader +++ b/crest/Assets/Crest/Crest/Shaders/OceanInputs/AnimWavesSpectrum.shader @@ -43,11 +43,12 @@ Shader "Crest/Inputs/Shape Waves/Sample Spectrum" half GetAttenuationInShallowsWeight(const Texture2DArray i_texture, const float3 i_uv) { - const half2 terrainHeight_seaLevelOffset = i_texture.SampleLevel(LODData_linear_clamp_sampler, i_uv, 0.0).xy; + half2 terrainHeight_seaLevelOffset = i_texture.SampleLevel(LODData_linear_clamp_sampler, i_uv, 0.0).xy; + terrainHeight_seaLevelOffset.x = max(terrainHeight_seaLevelOffset.x, -CREST_FLOAT_MAXIMUM); const half depth = _OceanCenterPosWorld.y - terrainHeight_seaLevelOffset.x + terrainHeight_seaLevelOffset.y; // Attenuate if depth is less than half of the average wavelength. half weight = saturate(2.0 * depth / _AverageWavelength); - if (_MaximumAttenuationDepth < CREST_OCEAN_DEPTH_BASELINE) + if (_MaximumAttenuationDepth < CREST_MAXIMUM_ATTENUATION_DEPTH) { weight = lerp(weight, 1.0, saturate(depth / _MaximumAttenuationDepth)); } diff --git a/crest/Assets/Crest/Crest/Shaders/OceanInputs/GerstnerShared.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanInputs/GerstnerShared.hlsl index c37c52714..812768556 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanInputs/GerstnerShared.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/OceanInputs/GerstnerShared.hlsl @@ -26,7 +26,8 @@ CBUFFER_END half3 ComputeGerstner(float2 worldPosXZ, float3 uv_slice) { // sample ocean depth (this render target should 1:1 match depth texture, so UVs are trivial) - const half2 terrainHeight_seaLevelOffset = _LD_TexArray_SeaFloorDepth.SampleLevel(LODData_linear_clamp_sampler, uv_slice, 0.0).xy; + half2 terrainHeight_seaLevelOffset = _LD_TexArray_SeaFloorDepth.SampleLevel(LODData_linear_clamp_sampler, uv_slice, 0.0).xy; + terrainHeight_seaLevelOffset.x = max(terrainHeight_seaLevelOffset.x, -CREST_FLOAT_MAXIMUM); const half depth = _OceanCenterPosWorld.y - terrainHeight_seaLevelOffset.x + terrainHeight_seaLevelOffset.y; // Preferred wave directions diff --git a/crest/Assets/Crest/Crest/Shaders/OceanInputs/Resources/AnimWavesGerstner.shader b/crest/Assets/Crest/Crest/Shaders/OceanInputs/Resources/AnimWavesGerstner.shader index 8c91d1e71..3bb18151c 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanInputs/Resources/AnimWavesGerstner.shader +++ b/crest/Assets/Crest/Crest/Shaders/OceanInputs/Resources/AnimWavesGerstner.shader @@ -73,11 +73,12 @@ Shader "Hidden/Crest/Inputs/Animated Waves/Gerstner Global" float wt = _Weight; // Attenuate if depth is less than half of the average wavelength - const half2 terrainHeight_seaLevelOffset = + half2 terrainHeight_seaLevelOffset = _LD_TexArray_SeaFloorDepth.SampleLevel(LODData_linear_clamp_sampler, float3(input.uv_uvWaves.xy, _LD_SliceIndex), 0.0).xy; + terrainHeight_seaLevelOffset.x = max(terrainHeight_seaLevelOffset.x, -CREST_FLOAT_MAXIMUM); const half depth = _OceanCenterPosWorld.y - terrainHeight_seaLevelOffset.x + terrainHeight_seaLevelOffset.y; half depth_wt = saturate(2.0 * depth / _AverageWavelength); - if (_MaximumAttenuationDepth < CREST_OCEAN_DEPTH_BASELINE) + if (_MaximumAttenuationDepth < CREST_MAXIMUM_ATTENUATION_DEPTH) { depth_wt = lerp(depth_wt, 1.0, saturate(depth / _MaximumAttenuationDepth)); } diff --git a/crest/Assets/Crest/Crest/Shaders/OceanInputs/Resources/AnimWavesGerstnerGeometry.shader b/crest/Assets/Crest/Crest/Shaders/OceanInputs/Resources/AnimWavesGerstnerGeometry.shader index 850de15ff..1a622f5b7 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanInputs/Resources/AnimWavesGerstnerGeometry.shader +++ b/crest/Assets/Crest/Crest/Shaders/OceanInputs/Resources/AnimWavesGerstnerGeometry.shader @@ -110,10 +110,11 @@ Shader "Crest/Inputs/Animated Waves/Gerstner Geometry" float wt = input.invNormDistToShoreline_weight.y; // Attenuate if depth is less than half of the average wavelength - const half2 terrainHeight_seaLevelOffset = _LD_TexArray_SeaFloorDepth.SampleLevel(LODData_linear_clamp_sampler, input.uv_slice, 0.0).xy; + half2 terrainHeight_seaLevelOffset = _LD_TexArray_SeaFloorDepth.SampleLevel(LODData_linear_clamp_sampler, input.uv_slice, 0.0).xy; + terrainHeight_seaLevelOffset.x = max(terrainHeight_seaLevelOffset.x, -CREST_FLOAT_MAXIMUM); const half depth = _OceanCenterPosWorld.y - terrainHeight_seaLevelOffset.x + terrainHeight_seaLevelOffset.y; half depth_wt = saturate(2.0 * depth / _AverageWavelength); - if (_MaximumAttenuationDepth < CREST_OCEAN_DEPTH_BASELINE) + if (_MaximumAttenuationDepth < CREST_MAXIMUM_ATTENUATION_DEPTH) { depth_wt = lerp(depth_wt, 1.0, saturate(depth / _MaximumAttenuationDepth)); } diff --git a/crest/Assets/Crest/Crest/Shaders/Resources/UpdateDynWaves.compute b/crest/Assets/Crest/Crest/Shaders/Resources/UpdateDynWaves.compute index 14eeb8282..0fa93fa0d 100644 --- a/crest/Assets/Crest/Crest/Shaders/Resources/UpdateDynWaves.compute +++ b/crest/Assets/Crest/Crest/Shaders/Resources/UpdateDynWaves.compute @@ -71,7 +71,8 @@ void UpdateDynWaves(uint3 id : SV_DispatchThreadID) const float3 uv_slice = float3(input_uv, sliceIndex); - const float2 terrainHeight_seaLevelOffset = _LD_TexArray_SeaFloorDepth.SampleLevel(LODData_linear_clamp_sampler, uv_slice, 0.0).xy; + float2 terrainHeight_seaLevelOffset = _LD_TexArray_SeaFloorDepth.SampleLevel(LODData_linear_clamp_sampler, uv_slice, 0.0).xy; + terrainHeight_seaLevelOffset.x = max(terrainHeight_seaLevelOffset.x, -CREST_FLOAT_MAXIMUM); const float waterDepth = _OceanCenterPosWorld.y - terrainHeight_seaLevelOffset.x + terrainHeight_seaLevelOffset.y; // Wave reflections off geometry. diff --git a/crest/Assets/Crest/Crest/Shaders/Resources/UpdateFoam.compute b/crest/Assets/Crest/Crest/Shaders/Resources/UpdateFoam.compute index 6a4b5f0be..81654c9b7 100644 --- a/crest/Assets/Crest/Crest/Shaders/Resources/UpdateFoam.compute +++ b/crest/Assets/Crest/Crest/Shaders/Resources/UpdateFoam.compute @@ -107,7 +107,8 @@ void UpdateFoam(uint3 id : SV_DispatchThreadID) // Add foam in shallow water. use the displaced position to ensure we add foam where world objects are. const float3 uv_slice_displaced = WorldToUV(worldPosXZ + disp.xz, cascadeData, sliceIndex); - const half2 terrainHeight_seaLevelOffset = _LD_TexArray_SeaFloorDepth.SampleLevel(LODData_linear_clamp_sampler, uv_slice_displaced, 0.0).xy; + half2 terrainHeight_seaLevelOffset = _LD_TexArray_SeaFloorDepth.SampleLevel(LODData_linear_clamp_sampler, uv_slice_displaced, 0.0).xy; + terrainHeight_seaLevelOffset.x = max(terrainHeight_seaLevelOffset.x, -CREST_FLOAT_MAXIMUM); const half signedOceanDepth = _OceanCenterPosWorld.y - terrainHeight_seaLevelOffset.x + terrainHeight_seaLevelOffset.y + disp.y; foam += _ShorelineFoamStrength * simDeltaTime * saturate(1.0 - signedOceanDepth / _ShorelineFoamMaxDepth); diff --git a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader index 4b0357185..4957e0a9e 100644 --- a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader +++ b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader @@ -199,7 +199,7 @@ Shader "Crest/Underwater Curtain" const half shadow = 1.0; const half sss = 0.0; - half seaFloorDepth = CREST_OCEAN_DEPTH_BASELINE; + half seaFloorDepth = 0.0; #if _SUBSURFACESHALLOWCOLOUR_ON { // compute scatter colour from cam pos. two scenarios this can be called: diff --git a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterEffectShared.hlsl b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterEffectShared.hlsl index d2d48ee5b..f879192eb 100644 --- a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterEffectShared.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterEffectShared.hlsl @@ -197,7 +197,7 @@ half3 ApplyUnderwaterEffect } #endif // _SHADOWS_ON - half seaFloorDepth = CREST_OCEAN_DEPTH_BASELINE; + half seaFloorDepth = 0.0; #if _SUBSURFACESHALLOWCOLOUR_ON { // compute scatter colour from cam pos. two scenarios this can be called: