Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add underwater sun occlusion #704

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion crest/Assets/Crest/Crest/Shaders/Ocean.shader
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
25 changes: 24 additions & 1 deletion crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down