diff --git a/crest/Assets/Crest/Crest/Shaders/Ocean.shader b/crest/Assets/Crest/Crest/Shaders/Ocean.shader index 695411d91..f1d6088a5 100644 --- a/crest/Assets/Crest/Crest/Shaders/Ocean.shader +++ b/crest/Assets/Crest/Crest/Shaders/Ocean.shader @@ -163,6 +163,14 @@ Shader "Crest/Ocean" // underwater effect is being used. [Enum(CullMode)] _CullMode("Cull Mode", Int) = 2 + [Header(Underwater Sun Occlusion)] + // Whether to occlude light scattering for the volume. + [Toggle] _UnderwaterSunOcclusion("Enable", Float) = 1 + // Strength of the occlusion through the underwater fog. + _UnderwaterSunOcclusionDistance("Sun Occlusion Distance Strength", Range(0.0, 1000.0)) = 100.0 + // Fall-off to affect directionality. + _UnderwaterSunOcclusionFallOff("Sun Occlusion Fall-Off", Range(0, 1.0)) = 0.5 + [Header(Flow)] // Flow is horizontal motion in water as demonstrated in the 'whirlpool' example scene. 'Create Flow Sim' must be // enabled on the OceanRenderer to generate flow data. @@ -231,6 +239,7 @@ Shader "Crest/Ocean" #pragma shader_feature_local _PROCEDURALSKY_ON #pragma shader_feature_local _UNDERWATER_ON + #pragma shader_feature_local _UNDERWATERSUNOCCLUSION_ON #pragma shader_feature_local _FLOW_ON #pragma shader_feature_local _SHADOWS_ON #pragma shader_feature_local _CLIPSURFACE_ON @@ -545,7 +554,7 @@ Shader "Crest/Ocean" // Compute color of ocean - in-scattered light + refracted scene const float baseCascadeScale = _CrestCascadeData[0]._scale; const float meshScaleLerp = instanceData._meshScaleLerp; - half3 scatterCol = ScatterColour(input.lodAlpha_worldXZUndisplaced_oceanDepth.w, _WorldSpaceCameraPos, lightDir, view, shadow.x, underwater, true, sss, meshScaleLerp, baseCascadeScale, cascadeData0); + half3 scatterCol = ScatterColour(input.lodAlpha_worldXZUndisplaced_oceanDepth.w, _WorldSpaceCameraPos, lightDir, view, sceneZ, shadow.x, underwater, true, sss, meshScaleLerp, baseCascadeScale, cascadeData0); half3 col = OceanEmission(view, n_pixel, lightDir, input.grabPos, pixelZ, uvDepth, sceneZ, sceneZ01, bubbleCol, _Normals, underwater, scatterCol, cascadeData0, cascadeData1); // Light that reflects off water surface diff --git a/crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl index cbfa762ae..dcf160d3d 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl @@ -47,9 +47,14 @@ uniform half _CausticsDistortionStrength; uniform half3 _DiffuseShadow; #endif +#if _UNDERWATERSUNOCCLUSION_ON +half _UnderwaterSunOcclusionDistance; +half _UnderwaterSunOcclusionFallOff; +#endif + half3 ScatterColour( in const half i_surfaceOceanDepth, in const float3 i_cameraPos, - in const half3 i_lightDir, in const half3 i_view, in const fixed i_shadow, + in const half3 i_lightDir, in const half3 i_view, in const float i_sceneZ, in const fixed i_shadow, in const bool i_underwater, in const bool i_outscatterLight, half sss, in const float i_meshScaleLerp, in const float i_scaleBase, in const CascadeParams cascadeData0) @@ -121,6 +126,24 @@ half3 ScatterColour( // Approximate subsurface scattering - add light when surface faces viewer. Use geometry normal - don't need high freqs. half towardsSun = pow(max(0., dot(i_lightDir, -i_view)), _SubSurfaceSunFallOff); + +#if _UNDERWATERSUNOCCLUSION_ON + if (i_underwater) + { + // Apply strength factor. Otherwise, occlusion will not be noticeable. + half sunOcclusion = saturate(i_sceneZ / _UnderwaterSunOcclusionDistance); + + // Only apply occlusion to depth buffer contents. + if (i_sceneZ < _ProjectionParams.z) + { + // Apply separate fall-off. + sunOcclusion += pow(1.0 - towardsSun, 1.0 - _UnderwaterSunOcclusionFallOff); + } + + towardsSun = lerp(0, towardsSun, saturate(sunOcclusion)); + } +#endif + half3 subsurface = (_SubSurfaceBase + _SubSurfaceSun * towardsSun) * _SubSurfaceColour.rgb * _LightColor0 * shadow; if (!i_underwater) subsurface *= (1.0 - v * v) * sss; diff --git a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader index 640445ea7..25cac0f81 100644 --- a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader +++ b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader @@ -46,6 +46,7 @@ Shader "Crest/Underwater Curtain" #pragma multi_compile_local __ _TRANSPARENCY_ON #pragma multi_compile_local __ _CAUSTICS_ON #pragma multi_compile_local __ _SHADOWS_ON + #pragma multi_compile_local __ _UNDERWATERSUNOCCLUSION_ON #pragma multi_compile_local __ _COMPILESHADERWITHDEBUGINFO_ON #if _COMPILESHADERWITHDEBUGINFO_ON @@ -210,7 +211,7 @@ Shader "Crest/Underwater Curtain" const float meshScaleLerp = _CrestPerCascadeInstanceData[_LD_SliceIndex]._meshScaleLerp; const float baseCascadeScale = _CrestCascadeData[0]._scale; - const half3 scatterCol = ScatterColour(depth, _WorldSpaceCameraPos, lightDir, view, shadow, true, true, sss, meshScaleLerp, baseCascadeScale, cascadeData0); + const half3 scatterCol = ScatterColour(depth, _WorldSpaceCameraPos, lightDir, view, sceneZ, shadow, true, true, sss, meshScaleLerp, baseCascadeScale, cascadeData0); half3 sceneColour = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_BackgroundTexture, input.grabPos.xy / input.grabPos.w).rgb;