This commit is contained in:
zhangjiajia
2026-05-06 16:56:59 +08:00
parent 575626d3e1
commit 81ffaaeca6
1373 changed files with 145920 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#ifndef d_WaveHarmonic_Crest_VolumeDebug
#define d_WaveHarmonic_Crest_VolumeDebug
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Macros.hlsl"
m_CrestNameSpace
float4 DebugRenderWaterMask(const bool isWaterSurface, const bool isUnderwater, const float mask, const float3 sceneColour)
{
// Red: surface front face when above water
// Green: surface back face when below water
// Cyan: background when above water
// Magenta: background when below water
if (isWaterSurface)
{
return float4(sceneColour * float3(mask >= CREST_MASK_ABOVE_SURFACE, mask <= CREST_MASK_BELOW_SURFACE, 0.0), 1.0);
}
else
{
return float4(sceneColour * float3(isUnderwater * 0.5, (1.0 - isUnderwater) * 0.5, 1.0), 1.0);
}
}
float4 DebugRenderStencil(float3 sceneColour)
{
float3 stencil = 1.0;
#if d_Crest_Portal
#if d_Crest_FogAfter
stencil = float3(1.0, 0.0, 0.0);
#elif d_Crest_FogBefore
stencil = float3(0.0, 1.0, 0.0);
#else
stencil = float3(0.0, 0.0, 1.0);
#endif
#endif
return float4(sceneColour * stencil, 1.0);
}
m_CrestNameSpaceEnd
#endif // d_WaveHarmonic_Crest_VolumeDebug

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f174da407e60e4ed1b24dd11f44c9cdc
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 94b454ee025f04f81b984c298e5ff145
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: df63a8d198812478985b6d0a5d68a59a
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 60072b568d64c40a485e0fc55012dc9f, type: 3}

View File

@@ -0,0 +1,224 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// NOTE: It is important that everything has a Crest prefix to avoid possible conflicts.
// NOTE: No keywords so no mask color/depth variants not available.
#ifndef d_WaveHarmonic_Crest_ApplyWaterVolumeFog
#define d_WaveHarmonic_Crest_ApplyWaterVolumeFog
#ifndef SHADERGRAPH_PREVIEW
// TODO: enable dithering?
#define k_DisableCaustics
#define k_DisableDithering
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings.Crest.hlsl"
#if (CREST_PORTALS != 0)
#define d_Crest_Portal 1
#endif
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Surface/Shim.hlsl"
// Uses SHADERPASS which is broken for everyone else.
#undef d_IsAdditionalLight
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Depth.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/UnderwaterShared.hlsl"
m_CrestNameSpace
static bool s_IsUnderWater;
static float s_FogDistance;
static half s_FogMultiplier;
static float2 s_PositionSS;
static float3 s_PositionWS;
static half3 s_ViewWS;
static float s_DepthRaw;
float3 ApplyFog(float3 color)
{
#if (CREST_DISCARD_ATMOSPHERIC_SCATTERING == 0)
if (!s_IsUnderWater)
{
return color;
}
#endif
return ApplyUnderwaterEffect
(
color,
s_DepthRaw,
0, // Caustics only
s_FogDistance,
s_ViewWS,
s_PositionSS,
s_PositionWS,
false, // No caustics
true, // TODO: implement
true, // TODO: implement
s_FogMultiplier
);
}
float3 NoFog(float3 color)
{
return color;
}
void SetUpFog(const float2 i_PositionNDC, const float3 i_PositionWS, const float i_DepthRaw, const half i_Multiplier)
{
#if !CREST_BIRP
// Uses SHADERPASS which is broken for everyone else.
#if CREST_SHADOWPASS
return;
#endif
#endif
const float2 positionSS = i_PositionNDC.xy * _ScreenSize.xy;
const half mask = LOAD_TEXTURE2D_X(_Crest_WaterMaskTexture, positionSS).r;
// Skip if not underwater. We could also "&& rawSurfaceDepth < i_DepthRaw" to
// exclude objects behind the front-faces from receiving atmospheric fog, but we
// are using transparent blending which leaves a bright outline due to the edges
// receiving insufficient fog. Excluding these objects from atmospheric fog gives
// little benefit.
if (mask >= CREST_MASK_NO_FOG && mask < CREST_MASK_ABOVE_SURFACE_KEPT)
{
return;
}
#if (CREST_DISCARD_ATMOSPHERIC_SCATTERING != 0)
#if !d_Transparent
// FIXME: Find alternative solution for new mask.
const float rawSurfaceDepth = LOAD_DEPTH_TEXTURE_X(_Crest_WaterMaskDepthTexture, positionSS).r;
// Skip discarding fog if opaque object is behind back-faces.
if (mask < CREST_MASK_NO_FOG && mask > CREST_MASK_BELOW_SURFACE_KEPT && i_DepthRaw < rawSurfaceDepth)
{
return;
}
#endif
#endif
// Get the largest distance.
float rawFogDistance = i_DepthRaw;
float fogDistanceOffset = _ProjectionParams.y;
float fogDistance = 0.0;
#if (CREST_PORTALS != 0)
if (!Portal::EvaluateFog(i_PositionNDC, mask, rawFogDistance, fogDistanceOffset))
{
return;
}
else
#endif
{
fogDistance = Utility::CrestLinearEyeDepth(rawFogDistance) - fogDistanceOffset;
}
s_IsUnderWater = true;
s_PositionSS = positionSS;
s_PositionWS = i_PositionWS;
s_ViewWS = GetWorldSpaceNormalizeViewDir(i_PositionWS);
s_FogDistance = fogDistance;
s_DepthRaw = i_DepthRaw;
s_FogMultiplier = i_Multiplier;
}
m_CrestNameSpaceEnd
#if d_Transparent
#define ApplyFog(x) ApplyFog(x)
#else
#define ApplyFog(x) NoFog(x)
#endif
#if CREST_BIRP
#ifdef UNITY_PASS_FORWARDADD
#define m_Unity_FogColor fixed4(0, 0, 0, 0)
#else
#define m_Unity_FogColor unity_FogColor
#endif // UNITY_PASS_FORWARDADD
#undef UNITY_APPLY_FOG
#if (CREST_DISCARD_ATMOSPHERIC_SCATTERING != 0)
#define UNITY_APPLY_FOG(coord, color) \
if (m_Crest::s_IsUnderWater) \
{ \
color.rgb = m_Crest::ApplyFog(color.rgb); \
} \
else \
{ \
UNITY_APPLY_FOG_COLOR(coord, color, m_Unity_FogColor); \
}
#else
#define UNITY_APPLY_FOG(coord, color) \
UNITY_APPLY_FOG_COLOR(coord, color, m_Unity_FogColor); \
color.rgb = m_Crest::ApplyFog(color.rgb);
#endif // CREST_DISCARD_ATMOSPHERIC_SCATTERING
#endif // CREST_BIRP
#if CREST_HDRP
#if (CREST_DISCARD_ATMOSPHERIC_SCATTERING != 0)
#define EvaluateAtmosphericScattering(i, V, color) m_Crest::s_IsUnderWater ? float4(m_Crest::ApplyFog(color.rgb), color.a) : EvaluateAtmosphericScattering(i, V, color)
#else
#define EvaluateAtmosphericScattering(i, V, color) EvaluateAtmosphericScattering(i, V, color); color.rgb = m_Crest::ApplyFog(color.rgb)
#endif
#endif
#if CREST_URP
#if (CREST_DISCARD_ATMOSPHERIC_SCATTERING != 0)
#define MixFog(color, coord) m_Crest::s_IsUnderWater ? m_Crest::ApplyFog(color) : MixFog(color, coord)
#else
#define MixFog(color, coord) MixFog(color, coord); color.rgb = m_Crest::ApplyFog(color.rgb)
#endif
#endif
#endif // SHADERGRAPH_PREVIEW
void CrestNodeIntegrateWaterVolume_half
(
const float2 i_PositionNDC,
const float3 i_PositionWS,
const float i_DepthRaw,
const half i_Multiplier,
const half4 i_Color,
const half3 i_Emission,
out half4 o_Color,
out half3 o_Emission
)
{
o_Color = i_Color;
o_Emission = i_Emission;
#ifndef SHADERGRAPH_PREVIEW
m_Crest::SetUpFog(i_PositionNDC, i_PositionWS, i_DepthRaw, i_Multiplier);
#endif
}
void CrestNodeIntegrateWaterVolume_float
(
const float2 i_PositionNDC,
const float3 i_PositionWS,
const float i_DepthRaw,
const half i_Multiplier,
const float4 i_Color,
const float3 i_Emission,
out float4 o_Color,
out float3 o_Emission
)
{
o_Color = i_Color;
o_Emission = i_Emission;
#ifndef SHADERGRAPH_PREVIEW
m_Crest::SetUpFog(i_PositionNDC, i_PositionWS, i_DepthRaw, i_Multiplier);
#endif
}
#endif // d_WaveHarmonic_Crest_ApplyWaterVolumeFog

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d71d6be33f63546ff8a3e48fa55faa5f
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,104 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
Shader "Hidden/Crest/Volume/Horizon Mask"
{
SubShader
{
PackageRequirements
{
"com.unity.render-pipelines.high-definition"
}
Tags { "RenderPipeline"="HDRenderPipeline" }
Blend Off
Cull Off
ZTest Always
ZWrite Off
Pass
{
Name "Water Horizon Mask"
Stencil
{
Ref [_Crest_StencilReference]
Comp [_Crest_StencilComparison]
}
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/MaskHorizon.hlsl"
ENDHLSL
}
}
SubShader
{
PackageRequirements
{
"com.unity.render-pipelines.universal"
}
Tags { "RenderPipeline"="UniversalPipeline" }
Blend Off
Cull Off
ZTest Always
ZWrite Off
Pass
{
Name "Water Horizon Mask"
Stencil
{
Ref [_Crest_StencilReference]
Comp [_Crest_StencilComparison]
}
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/MaskHorizon.hlsl"
ENDHLSL
}
}
SubShader
{
Blend Off
Cull Off
ZTest Always
ZWrite Off
Pass
{
Name "Water Horizon Mask"
Stencil
{
Ref [_Crest_StencilReference]
Comp [_Crest_StencilComparison]
}
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Core.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/MaskHorizon.hlsl"
ENDHLSL
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 80a81e5410296461d827cd6eed939b81
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma kernel CrestWaterLineBRP _BRP
#pragma kernel CrestWaterLineHRP _HRP
#pragma kernel CrestWaterLineURP _URP
// Not every RP handles this. HDRP seems to.
#pragma multi_compile __ STEREO_INSTANCING_ON
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/RP/Compute.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Constants.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Globals.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Surface/Data.hlsl"
RW_TEXTURE2D_X(float, _Crest_WaterMaskTexture);
m_CrestNameSpace
void WaterLine(const uint3 id)
{
UNITY_XR_ASSIGN_VIEW_INDEX(id.z);
float3 position = ComputeWorldSpacePosition(id.xy / _ScreenSize.xy, UNITY_NEAR_CLIP_VALUE, UNITY_MATRIX_I_VP);
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
position.xyz += _WorldSpaceCameraPos.xyz;
#endif
const float height = SampleWaterLineHeight(position.xz).x;
_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy)] = position.y <= height ? -1 : 1;
}
m_CrestNameSpaceEnd
m_CrestKernelXRP(WaterLine)

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 51ffca485396f4d8dbf07883c9303f3c
ComputeShaderImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,152 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#ifndef d_WaveHarmonic_Crest_Mask
#define d_WaveHarmonic_Crest_Mask
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings.Crest.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Constants.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Globals.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Helpers.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Surface/Geometry.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Depth.hlsl"
#if (CREST_PORTALS != 0)
#include "Packages/com.waveharmonic.crest.portals/Runtime/Shaders/Library/Portals.hlsl"
#endif
m_CrestNameSpace
struct Attributes
{
// The old unity macros require this name and type.
float4 positionCS : POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
#if d_LodInput
float3 positionWS : TEXCOORD;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings Vertex(const Attributes i_Input)
{
// This will work for all pipelines.
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(i_Input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
const uint slice0 = _Crest_LodIndex;
const uint slice1 = _Crest_LodIndex + 1;
const Cascade cascade0 = Cascade::Make(slice0);
const Cascade cascade1 = Cascade::Make(slice1);
float3 positionWS = mul(UNITY_MATRIX_M, float4(i_Input.positionCS.xyz, 1.0)).xyz;
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
positionWS.xz += _WorldSpaceCameraPos.xz;
#endif
float alpha;
SnapAndTransitionVertLayout(_Crest_ChunkMeshScaleAlpha, cascade0, _Crest_ChunkGeometryGridWidth, positionWS, alpha);
{
// Scale up by small "epsilon" to solve numerical issues. Expand slightly about tile center.
// :WaterGridPrecisionErrors
float2 tileCenterXZ = UNITY_MATRIX_M._m03_m23;
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
tileCenterXZ += _WorldSpaceCameraPos.xz;
#endif
const float2 cameraPositionXZ = abs(_WorldSpaceCameraPos.xz);
positionWS.xz = lerp(tileCenterXZ, positionWS.xz, lerp(1.0, 1.01, max(cameraPositionXZ.x, cameraPositionXZ.y) * 0.00001));
}
const float weight0 = (1.0 - alpha) * cascade0._Weight;
const float weight1 = (1.0 - weight0) * cascade1._Weight;
const float2 positionXZ = positionWS.xz;
// Data that needs to be sampled at the undisplaced position.
if (weight0 > m_CrestSampleLodThreshold)
{
Cascade::MakeAnimatedWaves(slice0).SampleDisplacement(positionXZ, weight0, positionWS);
}
if (weight1 > m_CrestSampleLodThreshold)
{
Cascade::MakeAnimatedWaves(slice1).SampleDisplacement(positionXZ, weight1, positionWS);
}
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
positionWS.xz -= _WorldSpaceCameraPos.xz;
#endif
output.positionCS = mul(UNITY_MATRIX_VP, float4(positionWS, 1.0));
#if d_LodInput
output.positionWS = positionWS;
#endif
return output;
}
half4 Fragment(const Varyings i_Input, const bool i_FrontFace)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i_Input);
#if d_LodInput
return half4(i_Input.positionWS.y - g_Crest_WaterCenter.y, 0, 0, 1);
#endif
half result = 0.0;
#if (CREST_PORTALS != 0)
#if !d_Tunnel
if (m_CrestPortal)
{
Portal::EvaluateMask(i_Input.positionCS);
}
#endif
#endif
if (IsUnderWater(i_FrontFace, g_Crest_ForceUnderwater))
{
result = CREST_MASK_BELOW_SURFACE;
}
else
{
result = CREST_MASK_ABOVE_SURFACE;
}
#if (CREST_PORTALS != 0)
#if d_Crest_NegativeVolumePass
result = Portal::FixMaskForNegativeVolume(result, i_Input.positionCS.xy);
#endif
#if d_Tunnel
const float2 positionSS = i_Input.positionCS.xy;
const float ffz = LOAD_DEPTH_TEXTURE_X(_Crest_PortalFogBeforeTexture, positionSS);
const float bfz = LOAD_DEPTH_TEXTURE_X(_Crest_PortalFogAfterTexture, positionSS);
if (ffz <= 0.0 && bfz > 0.0)
{
result = CREST_MASK_ABOVE_SURFACE;
}
#endif
#endif
return (half4)result;
}
m_CrestNameSpaceEnd
m_CrestVertex
m_CrestFragmentWithFrontFace(half4)
#endif // d_WaveHarmonic_Crest_Mask

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b891a37e4cd634b03888a64e8965920b
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,232 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
Shader "Hidden/Crest/Underwater/Water Surface Mask"
{
SubShader
{
PackageRequirements
{
"com.unity.render-pipelines.high-definition"
}
Tags { "RenderPipeline"="HDRenderPipeline" }
Pass
{
Name "Water Surface Mask"
// We always disable culling when rendering water mask, as we only
// use it for underwater rendering features.
Cull Off
Stencil
{
Ref [_Crest_StencilReference]
Comp [_Crest_StencilComparison]
}
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
// for VFACE
#pragma target 3.0
#pragma multi_compile_local_fragment __ d_Tunnel
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDHLSL
}
Pass
{
Name "Water Surface Mask (Negative Volume)"
Cull Off
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
// for VFACE
#pragma target 3.0
#define m_Return discard
#define d_Crest_NegativeVolumePass 1
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDHLSL
}
Pass
{
Name "Water Surface Data"
Cull Back
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
#pragma target 3.0
#define d_LodInput 1
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDHLSL
}
}
SubShader
{
PackageRequirements
{
"com.unity.render-pipelines.universal"
}
Tags { "RenderPipeline"="UniversalPipeline" }
Pass
{
Name "Water Surface Mask"
// We always disable culling when rendering water mask, as we only
// use it for underwater rendering features.
Cull Off
Stencil
{
Ref [_Crest_StencilReference]
Comp [_Crest_StencilComparison]
}
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
// for VFACE
#pragma target 3.0
#pragma multi_compile_local_fragment __ d_Tunnel
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDHLSL
}
Pass
{
Name "Water Surface Mask (Negative Volume)"
Cull Off
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
// for VFACE
#pragma target 3.0
#define m_Return discard
#define d_Crest_NegativeVolumePass 1
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDHLSL
}
Pass
{
Name "Water Surface Data"
Cull Back
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
#pragma target 3.0
#define d_LodInput 1
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDHLSL
}
}
SubShader
{
Pass
{
Name "Water Surface Mask"
// We always disable culling when rendering water mask, as we only
// use it for underwater rendering features.
Cull Off
Stencil
{
Ref [_Crest_StencilReference]
Comp [_Crest_StencilComparison]
}
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
// for VFACE
#pragma target 3.0
#pragma multi_compile_local_fragment __ d_Tunnel
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Core.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDHLSL
}
Pass
{
Name "Water Surface Mask (Negative Volume)"
Cull Off
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
// for VFACE
#pragma target 3.0
#define m_Return discard
#define d_Crest_NegativeVolumePass 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Core.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDHLSL
}
Pass
{
Name "Water Surface Data"
Cull Back
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
#pragma target 3.0
#define d_LodInput 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Core.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDHLSL
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: edb653e62cc924b99b0a1086ffb39be7
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// Checks both orthogonal and diagonal pixels to fill artefacts in the mask. If checked pixels are all the same then it
// assumes that the current pixel should also be the same and fixes it.
#pragma kernel FillMaskArtefacts _BRP
// Built-in will not handle this for us unlike other RPs.
#pragma multi_compile __ STEREO_INSTANCING_ON
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/RP/Compute.hlsl"
RW_TEXTURE2D_X(float, _Crest_WaterMaskTexture);
[numthreads(8, 8, 1)]
void FillMaskArtefacts(const uint3 id : SV_DispatchThreadID)
{
UNITY_XR_ASSIGN_VIEW_INDEX(id.z);
const uint3 offset = uint3(1, -1, 0);
// Check orthogonal pixels.
{
const float4 pixels = float4
(
_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy + offset.xz)],
_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy + offset.yz)],
_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy + offset.zy)],
_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy + offset.zx)]
);
// If these pixels are all the same, then it is valid that this pixel also equals them.
if (pixels.x == pixels.y && pixels.y == pixels.z && pixels.z == pixels.w)
{
_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy)] = pixels.x;
return;
}
}
// Check diagonal pixels.
{
const float4 pixels = float4
(
_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy + offset.xx)],
_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy + offset.yy)],
_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy + offset.xy)],
_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy + offset.yx)]
);
// If these pixels are all the same, then it is valid that this pixel also equals them.
if (pixels.x == pixels.y && pixels.y == pixels.z && pixels.z == pixels.w)
{
_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy)] = pixels.x;
return;
}
}
_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy)] = _Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy)];
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 08549c36146ad4899a07193754b21ea2
ComputeShaderImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// Renders the water horizon line into the mask.
#ifndef CREST_UNDERWATER_MASK_HORIZON_SHARED_INCLUDED
#define CREST_UNDERWATER_MASK_HORIZON_SHARED_INCLUDED
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Constants.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Globals.hlsl"
// Driven by scripting. It is a non-linear converted from a linear 0-1 value.
float _Crest_FarPlaneOffset;
struct Attributes
{
uint id : SV_VertexID;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings Vertex(Attributes input)
{
// This will work for all pipelines.
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
output.positionCS = GetFullScreenTriangleVertexPosition(input.id, _Crest_FarPlaneOffset);
output.uv = GetFullScreenTriangleTexCoord(input.id);
return output;
}
half4 Fragment(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float3 positionWS = ComputeWorldSpacePosition(input.uv, _Crest_FarPlaneOffset, UNITY_MATRIX_I_VP);
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
positionWS.y += _WorldSpaceCameraPos.y;
#endif
return (half4) positionWS.y > g_Crest_WaterCenter.y
? CREST_MASK_ABOVE_SURFACE
: CREST_MASK_BELOW_SURFACE;
}
#endif // CREST_UNDERWATER_MASK_HORIZON_SHARED_INCLUDED

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5f5a4cb92ecd4468e84893f8257be090
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,203 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/UnderwaterShared.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Debug.hlsl"
#ifndef SUPPORTS_FOVEATED_RENDERING_NON_UNIFORM_RASTER
#define FoveatedRemapLinearToNonUniform(uv) uv
#endif
#if (CREST_LEGACY_UNDERWATER != 0) || d_Crest_CustomColorTexture
TEXTURE2D_X(_Crest_CameraColorTexture);
#endif
#if d_Crest_ComputeMask
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Surface/Data.hlsl"
#endif
m_CrestNameSpace
#if (CREST_LEGACY_UNDERWATER != 0)
float3 SampleSceneColor(float2 i_UV)
{
return LOAD_TEXTURE2D_X(_Crest_CameraColorTexture, i_UV * _ScreenSize.xy).rgb;
}
#endif
struct Attributes
{
#if d_Crest_Geometry
float3 positionOS : POSITION;
#else
uint id : SV_VertexID;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
#if d_Crest_ComputeMask
float3 positionWS : TEXCOORD;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings Vertex(Attributes input)
{
Varyings output;
ZERO_INITIALIZE(Varyings, output);
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if d_Crest_Geometry
// Use actual geometry instead of full screen triangle.
output.positionCS = TransformObjectToHClip(input.positionOS);
#if d_Crest_ComputeMask
output.positionWS = TransformObjectToWorld(input.positionOS);
#endif
#else
output.positionCS = GetFullScreenTriangleVertexPosition(input.id, UNITY_RAW_FAR_CLIP_VALUE);
#endif
return output;
}
half4 Fragment(Varyings input)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
uint2 positionSS = input.positionCS.xy;
const float2 positionNDC = (positionSS + 0.5) / _ScreenSize.xy;
float mask = -1.0;
#if !d_Crest_NoMaskColor
#if d_Crest_ComputeMask
{
float3 positionWS = input.positionWS;
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
positionWS.xyz += _WorldSpaceCameraPos.xyz;
#endif
mask = positionWS.y <= SampleWaterLineHeight(positionWS.xz) ? -1 : 1;
}
#else
mask = LOAD_TEXTURE2D_X(_Crest_WaterMaskTexture, positionSS).x;
#endif
#if !_DEBUG_VISUALIZE_MASK
// Preserve alpha channel.
if (mask > CREST_MASK_BELOW_SURFACE)
{
discard;
}
#endif
#endif // !d_Crest_NoMaskColor
float rawDepth = LoadSceneDepth(positionSS);
half3 sceneColour;
#if d_Crest_CustomColorTexture
if (m_CrestPortalNegativeVolume)
{
sceneColour = LOAD_TEXTURE2D_X(_Crest_CameraColorTexture, positionSS).rgb;
}
else
#endif
{
// Use sample in case texture is downsampled.
sceneColour = SampleSceneColor(positionNDC).rgb;
}
#if d_Crest_NoMaskDepth
const float rawMaskDepth = 0.0;
#else
const float rawMaskDepth = LOAD_TEXTURE2D_X(_Crest_WaterMaskDepthTexture, positionSS).x;
#endif
#if _DEBUG_VISUALIZE_STENCIL
return DebugRenderStencil(sceneColour);
#endif
bool isWaterSurface; bool isUnderwater; bool hasCaustics; float sceneZ; bool outScatterScene; bool applyLighting;
GetWaterSurfaceAndUnderwaterData(input.positionCS, positionSS, rawMaskDepth, mask, rawDepth, isWaterSurface, isUnderwater, hasCaustics, outScatterScene, applyLighting, sceneZ);
#if !_DEBUG_VISUALIZE_MASK
// Preserve alpha channel.
if (!isUnderwater)
{
discard;
}
#endif
float fogDistance = sceneZ;
ApplyWaterVolumeToUnderwaterFog(input.positionCS, fogDistance);
#if _DEBUG_VISUALIZE_MASK
return DebugRenderWaterMask(isWaterSurface, isUnderwater, mask, sceneColour);
#endif
if (isUnderwater)
{
const float2 uv = FoveatedRemapLinearToNonUniform(positionNDC);
float3 positionWS = ComputeWorldSpacePosition(uv, rawDepth, UNITY_MATRIX_I_VP);
const half3 view = GetWorldSpaceNormalizeViewDir(positionWS);
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
positionWS += _WorldSpaceCameraPos;
#endif
sceneColour = ApplyUnderwaterEffect(sceneColour, rawDepth, sceneZ, fogDistance, view, positionSS, positionWS, hasCaustics, outScatterScene, applyLighting, 1.0);
}
return half4(sceneColour, 1.0);
}
half4 FragmentPlanarReflections(Varyings input)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
const uint2 positionSS = input.positionCS.xy;
const float2 positionNDC = (positionSS + 0.5) / _ScreenSize.xy;
float depth = LoadSceneDepth(positionSS);
// TODO: Do something nicer. Could zero alpha if scene depth is above threshold.
if (depth == 0.0)
{
return half4(_Crest_Scattering.xyz, 1.0);
}
half3 color = SampleSceneColor(positionNDC).rgb;
// Calculate position and account for possible NaNs discovered during testing.
float3 positionWS;
{
float4 positionCS = ComputeClipSpacePosition(positionNDC, depth);
float4 hpositionWS = mul(UNITY_MATRIX_I_VP, positionCS);
// w is sometimes zero when using oblique projection.
// Zero is better than NaN.
positionWS = hpositionWS.w > 0.0 ? hpositionWS.xyz / hpositionWS.w : 0.0;
}
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
positionWS += _WorldSpaceCameraPos;
#endif
const half3 view = GetWorldSpaceNormalizeViewDir(positionWS);
const bool hasCaustics = depth > 0.0;
color = ApplyUnderwaterEffect(color, depth, 0.0, 0.0, view, positionSS, positionWS, hasCaustics, true, true, 1.0);
return half4(color, 1.0);
}
m_CrestNameSpaceEnd
m_CrestVertex
m_CrestFragment(half4)
half4 FragmentPlanarReflections(m_Crest::Varyings input) : SV_Target
{
return m_Crest::FragmentPlanarReflections(input);
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2636ae353ea154204861c022e68003df
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,760 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
Shader "Crest/Underwater"
{
Properties
{
_Crest_ExtinctionMultiplier("Density Factor", Range(0, 1)) = 1
_Crest_SunBoost("Sun Boost", Range(0, 100)) = 2
_Crest_OutScatteringFactor("Out-Scattering Factor", Range(0, 1)) = 0.2
_Crest_OutScatteringExtinctionFactor("Out-Scattering Extinction Factor", Range(0, 1)) = 0.2
[Space(10)]
[Toggle(d_Dithering)]
_Crest_DitheringEnabled("Dithering", Integer) = 1
_Crest_DitheringIntensity("Dithering Intensity", Range(0, 10)) = 1
[Header(Advanced)]
[Space(6)]
// This adds an offset to the cascade index when sampling water data, in effect smoothing/blurring it. Default
// to shifting the maximum amount (shift from lod 0 to penultimate lod - dont use last lod as it cross-fades
// data in/out), as more filtering was better in testing.
[CrestIntegerRange]
_Crest_DataSliceOffset("Filter Water Data", Integer) = 13
[HideInInspector]
_Crest_Version("Version", Integer) = 0
[Header(Copied From Water Surface)]
[Space(6)]
[PerRendererData] _Crest_AbsorptionColor("Absorption Color", Color) = (0.3416268, 0.6954546, 0.85, 0.1019608)
[PerRendererData] _Crest_Scattering("Scattering", Color) = (0, 0.09803922, 0.2, 1)
[PerRendererData] _Crest_Anisotropy("Anisotropy", Range(0, 1)) = 0.5
[PerRendererData] _Crest_DirectTerm("Direct Term", Float) = 1
[PerRendererData] _Crest_AmbientTerm("Ambient Term", Float) = 1
[PerRendererData] _Crest_ShadowsAffectsAmbientFactor("Shadows Affects Ambient Factor", Float) = 0.5
// Caustics
[PerRendererData] [ToggleUI] _Crest_CausticsEnabled("Caustics Enabled", Float) = 1
[PerRendererData] [NoScaleOffset] _Crest_CausticsTexture("Caustics Texture", 2D) = "black" {}
[PerRendererData] _Crest_CausticsStrength("Caustics Strength", Range(0, 10)) = 3.2
[PerRendererData] _Crest_CausticsTextureScale("Caustics Scale", Range(0.01, 100)) = 50
[PerRendererData] _Crest_CausticsScrollSpeed("Caustics Scroll Speed", Range(0, 10)) = 1
[PerRendererData] _Crest_CausticsTextureAverage("Caustics Grey Point", Range(0, 1)) = 0.07
[PerRendererData] _Crest_CausticsFocalDepth("Caustics Focal Depth", Range(0, 25)) = 2
[PerRendererData] _Crest_CausticsDepthOfField("Caustics Depth of Field", Range(0.01, 10)) = 6
[PerRendererData] [NoScaleOffset] _Crest_CausticsDistortionTexture("Caustics Distortion Texture", 2D) = "grey" {}
[PerRendererData] _Crest_CausticsDistortionStrength("Caustics Distortion Strength", Range(0, 0.25)) = 0.16
[PerRendererData] _Crest_CausticsDistortionScale("Caustics Distortion Scale", Range(0.01, 1000)) = 250
[PerRendererData] _Crest_CausticsMotionBlur("Caustics Motion Blur", Range(0, 10)) = 1
[PerRendererData] [Toggle] CREST_FLOW("Flow Enabled", Float) = 0
}
HLSLINCLUDE
#pragma vertex Vertex
// #pragma enable_d3d11_debug_symbols
// Also on the water shader.
#pragma multi_compile_local_fragment __ CREST_FLOW_ON
#pragma shader_feature_local_fragment __ d_Dithering
// NOTE: FragmentPlanarReflections do not need these.
// Whether to skip mask and/or depth sampling.
#pragma multi_compile_local_fragment __ d_Crest_NoMaskColor
#pragma multi_compile_local_fragment __ d_Crest_NoMaskDepth
#pragma multi_compile_local_fragment __ _DEBUG_VISUALIZE_MASK
#pragma multi_compile_local_fragment __ _DEBUG_VISUALIZE_STENCIL
ENDHLSL
SubShader
{
PackageRequirements
{
"com.unity.render-pipelines.high-definition"
}
Tags { "RenderPipeline"="HDRenderPipeline" }
Blend Off
Cull Off
ZTest Always
ZWrite Off
Pass
{
Name "Full Screen"
HLSLPROGRAM
#include_with_pragmas "UnderwaterHDRP.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
Name "Reflection"
HLSLPROGRAM
#define CREST_REFLECTION 1
#include_with_pragmas "UnderwaterHDRP.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment FragmentPlanarReflections
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Fog After"
Cull Back
ZTest LEqual
HLSLPROGRAM
#include_with_pragmas "UnderwaterHDRP.hlsl"
#pragma multi_compile_local _ d_Crest_ComputeMask
#define d_Crest_Portal 1
#define d_Crest_Geometry 1
#define d_Crest_FogAfter 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Fog After To Back-Face"
Cull Back
ZTest LEqual
HLSLPROGRAM
#include_with_pragmas "UnderwaterHDRP.hlsl"
#define d_Crest_Portal 1
#define d_Crest_Geometry 1
#define d_Crest_PortalWithBackFace 1
#define d_Crest_FogAfter 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Fog After To Back-Face (Fly-Through)"
Cull Back
ZTest LEqual
Stencil
{
// Must match k_StencilValueVolume in:
// Portals.cs
Ref 5
Comp Always
Pass Replace
ZFail IncrSat
}
HLSLPROGRAM
#include_with_pragmas "UnderwaterHDRP.hlsl"
#pragma multi_compile_local _ d_Crest_ComputeMask
#define d_Crest_Portal 1
#define d_Crest_Geometry 1
#define d_Crest_PortalWithBackFace 1
#define d_Crest_FogAfter 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
// Back face will only render if view is within the volume and there is no scene in front. It will only add
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// fog to the back face (and in effect anything behind it). No caustics.
Name "Fog Before (Fly-Through)"
Cull Front
ZTest LEqual
Stencil
{
// Must match k_StencilValueVolume in:
// Portals.cs
Ref 5
Comp NotEqual
Pass Replace
ZFail IncrSat
}
HLSLPROGRAM
#include_with_pragmas "UnderwaterHDRP.hlsl"
#define d_Crest_CustomColorTexture 1
#define d_Crest_Portal 1
#define d_Crest_Geometry 1
#define d_Crest_FogBefore 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// When inside a volume, this pass will render to the scene within the volume.
Name "Full Screen (Fly-Through)"
Stencil
{
// We want to render over the scene that's inside the volume, but not over already fogged areas. It will
// handle all of the scene within the geometry once the camera is within the volume.
// 0 = Outside of geometry as neither face passes have touched it.
// 1 = Only back face z failed which means scene is in front of back face but not front face.
// 2 = Both front and back face z failed which means outside geometry.
Ref 1
Comp Equal
Pass Replace
}
HLSLPROGRAM
#include_with_pragmas "UnderwaterHDRP.hlsl"
#define d_Crest_Portal 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
Name "Full Screen (Negative)"
HLSLPROGRAM
#include_with_pragmas "UnderwaterHDRP.hlsl"
#define d_Crest_CustomColorTexture 1
#define d_Crest_Portal 1
#define d_Crest_PortalNegativeVolume 1
#define d_Crest_PortalWithBackFace 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
}
SubShader
{
PackageRequirements
{
"com.unity.render-pipelines.universal"
}
Tags { "RenderPipeline"="UniversalPipeline" }
Blend Off
Cull Off
ZTest Always
ZWrite Off
Pass
{
Name "Full Screen"
HLSLPROGRAM
#include_with_pragmas "UnderwaterURP.hlsl"
#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
Name "Reflection"
HLSLPROGRAM
#define CREST_REFLECTION 1
#include_with_pragmas "UnderwaterURP.hlsl"
#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment FragmentPlanarReflections
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Fog After"
Cull Back
ZTest LEqual
HLSLPROGRAM
#include_with_pragmas "UnderwaterURP.hlsl"
#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
#pragma multi_compile_local _ d_Crest_ComputeMask
#define d_Crest_Portal 1
#define d_Crest_Geometry 1
#define d_Crest_FogAfter 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Fog After To Back-Face"
Cull Back
ZTest LEqual
HLSLPROGRAM
#include_with_pragmas "UnderwaterURP.hlsl"
#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
#define d_Crest_Portal 1
#define d_Crest_Geometry 1
#define d_Crest_PortalWithBackFace 1
#define d_Crest_FogAfter 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Fog After To Back-Face (Fly-Through)"
Cull Back
ZTest LEqual
Stencil
{
// Must match k_StencilValueVolume in:
// Portals.cs
Ref 5
Comp Always
Pass Replace
ZFail IncrSat
}
HLSLPROGRAM
#include_with_pragmas "UnderwaterURP.hlsl"
#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
#pragma multi_compile_local _ d_Crest_ComputeMask
#define d_Crest_Portal 1
#define d_Crest_Geometry 1
#define d_Crest_PortalWithBackFace 1
#define d_Crest_FogAfter 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
// Back face will only render if view is within the volume and there is no scene in front. It will only add
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// fog to the back face (and in effect anything behind it). No caustics.
Name "Fog Before (Fly-Through)"
Cull Front
ZTest LEqual
Stencil
{
// Must match k_StencilValueVolume in:
// Portals.cs
Ref 5
Comp NotEqual
Pass Replace
ZFail IncrSat
}
HLSLPROGRAM
#include_with_pragmas "UnderwaterURP.hlsl"
#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
#define d_Crest_CustomColorTexture 1
#define d_Crest_Portal 1
#define d_Crest_Geometry 1
#define d_Crest_FogBefore 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// When inside a volume, this pass will render to the scene within the volume.
Name "Full Screen (Fly-Through)"
Stencil
{
// We want to render over the scene that's inside the volume, but not over already fogged areas. It will
// handle all of the scene within the geometry once the camera is within the volume.
// 0 = Outside of geometry as neither face passes have touched it.
// 1 = Only back face z failed which means scene is in front of back face but not front face.
// 2 = Both front and back face z failed which means outside geometry.
Ref 1
Comp Equal
Pass Replace
}
HLSLPROGRAM
#include_with_pragmas "UnderwaterURP.hlsl"
#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
#define d_Crest_Portal 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
Name "Full Screen (Negative)"
HLSLPROGRAM
#include_with_pragmas "UnderwaterURP.hlsl"
#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
#define d_Crest_CustomColorTexture 1
#define d_Crest_Portal 1
#define d_Crest_PortalNegativeVolume 1
#define d_Crest_PortalWithBackFace 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
}
SubShader
{
Blend Off
Cull Off
ZTest Always
ZWrite Off
Pass
{
Name "Full Screen"
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
Name "Reflection"
HLSLPROGRAM
#define CREST_REFLECTION 1
#include_with_pragmas "UnderwaterBIRP.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment FragmentPlanarReflections
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Fog After"
Cull Back
ZTest LEqual
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#pragma multi_compile_local _ d_Crest_ComputeMask
#define d_Crest_Portal 1
#define d_Crest_Geometry 1
#define d_Crest_FogAfter 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Fog After To Back-Face"
Cull Back
ZTest LEqual
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#define d_Crest_Portal 1
#define d_Crest_Geometry 1
#define d_Crest_PortalWithBackFace 1
#define d_Crest_FogAfter 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Fog After To Back-Face (Fly-Through)"
Cull Back
ZTest LEqual
Stencil
{
// Must match k_StencilValueVolume in:
// Portals.cs
Ref 5
Comp Always
Pass Replace
ZFail IncrSat
}
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#define d_Crest_Portal 1
#define d_Crest_Geometry 1
#define d_Crest_PortalWithBackFace 1
#define d_Crest_FogAfter 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
// Back face will only render if view is within the volume and there is no scene in front. It will only add
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// fog to the back face (and in effect anything behind it). No caustics.
Name "Fog Before (Fly-Through)"
Cull Front
ZTest LEqual
Stencil
{
// Must match k_StencilValueVolume in:
// Portals.cs
Ref 5
Comp NotEqual
Pass Replace
ZFail IncrSat
}
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#pragma multi_compile_local _ d_Crest_ComputeMask
// For negative volumes.
#define d_Crest_CustomColorTexture 1
#define d_Crest_Portal 1
#define d_Crest_Geometry 1
#define d_Crest_FogBefore 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
// When inside a volume, this pass will render to the scene within the volume.
Name "Full Screen (Fly-Through)"
Stencil
{
// We want to render over the scene that's inside the volume, but not over already fogged areas. It will
// handle all of the scene within the geometry once the camera is within the volume.
// 0 = Outside of geometry as neither face passes have touched it.
// 1 = Only back face z failed which means scene is in front of back face but not front face.
// 2 = Both front and back face z failed which means outside geometry.
Ref 1
Comp Equal
Pass Replace
}
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#define d_Crest_Portal 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
Name "Full Screen (Negative)"
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#define d_Crest_CustomColorTexture 1
#define d_Crest_Portal 1
#define d_Crest_PortalNegativeVolume 1
#define d_Crest_PortalWithBackFace 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
}
CustomEditor "WaveHarmonic.Crest.Editor.CustomShaderGUI"
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 034b985bd9c344992af148e26d2cdb24
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#define BUILTIN_TARGET_API 1
#define CREST_BIRP 1
#define CREST_SHADERGRAPH_CONSTANTS_H
#pragma multi_compile_fragment _ DIRECTIONAL_COOKIE
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Includes/ShaderPass.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Defines.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Core.hlsl"
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Includes/LegacySurfaceVertex.hlsl"
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/ShaderGraphFunctions.hlsl"
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/DeclareOpaqueTexture.hlsl"
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/DeclareDepthTexture.hlsl"

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 765d2ceee80af4bd5a637f79488a3433
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma target 4.5
// Low appears good enough as it has filtering which is necessary when close to a shadow.
#define SHADOW_LOW
#define AREA_SHADOW_LOW
// In shared SG code we target the forward pass to avoid shader compilation errors.
#define CREST_HDRP 1
#define SHADERPASS SHADERPASS_FORWARD
#define CREST_HDRP_FORWARD_PASS 1
#define CREST_SHADERGRAPH_CONSTANTS_H
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/RP/HDRP/Common.hlsl"

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3b3db686f3a7746698c6193fcdc22ff2
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,346 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#ifndef CREST_UNDERWATER_EFFECT_SHARED_INCLUDED
#define CREST_UNDERWATER_EFFECT_SHARED_INCLUDED
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings.Crest.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Constants.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Globals.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Helpers.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Depth.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Helpers.hlsl"
#if d_Crest_Portal
#include "Packages/com.waveharmonic.crest.portals/Runtime/Shaders/Library/Portals.hlsl"
#endif
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Texture.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Lighting.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Shadows.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Surface/VolumeLighting.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Surface/Caustics.hlsl"
// These are set via call to CopyPropertiesFromMaterial() and must have the same
// names as the surface material parameters.
CBUFFER_START(CrestPerMaterial)
//
// Surface Shared
//
#ifndef d_Crest_WaterSurface
half4 _Crest_Absorption;
half4 _Crest_Scattering;
half _Crest_Anisotropy;
half _Crest_DirectTerm;
half _Crest_AmbientTerm;
half _Crest_ShadowsAffectsAmbientFactor;
bool _Crest_CausticsEnabled;
float _Crest_CausticsTextureScale;
float _Crest_CausticsScrollSpeed;
float _Crest_CausticsTextureAverage;
float _Crest_CausticsStrength;
float _Crest_CausticsFocalDepth;
float _Crest_CausticsDepthOfField;
float _Crest_CausticsDistortionStrength;
float _Crest_CausticsDistortionScale;
half _Crest_CausticsMotionBlur;
float4 _Crest_CausticsTexture_TexelSize;
float4 _Crest_CausticsDistortionTexture_TexelSize;
#endif // !d_Crest_WaterSurface
//
// Volume Only
//
// Out-scattering. Driven by the Water Renderer and Underwater Environmental Lighting.
float _Crest_VolumeExtinctionLength;
float _Crest_UnderwaterEnvironmentalLightingWeight;
// Also applied to transparent objects.
half _Crest_ExtinctionMultiplier;
half _Crest_SunBoost;
float _Crest_OutScatteringFactor;
float _Crest_OutScatteringExtinctionFactor;
half3 _Crest_AmbientLighting;
int _Crest_DataSliceOffset;
half _Crest_DitheringIntensity;
CBUFFER_END
TEXTURE2D_X(_Crest_WaterMaskDepthTexture);
#ifndef d_Crest_WaterSurface
TEXTURE2D_X(_Crest_WaterMaskTexture);
TEXTURE2D(_Crest_CausticsTexture);
SAMPLER(sampler_Crest_CausticsTexture);
TEXTURE2D(_Crest_CausticsDistortionTexture);
SAMPLER(sampler_Crest_CausticsDistortionTexture);
// NOTE: Cannot put this in namespace due to compiler bug. Fixed when using DXC.
static const m_Crest::TiledTexture _Crest_CausticsTiledTexture =
m_Crest::TiledTexture::Make(_Crest_CausticsTexture, sampler_Crest_CausticsTexture, _Crest_CausticsTexture_TexelSize, _Crest_CausticsTextureScale, _Crest_CausticsScrollSpeed);
static const m_Crest::TiledTexture _Crest_CausticsDistortionTiledTexture =
m_Crest::TiledTexture::Make(_Crest_CausticsDistortionTexture, sampler_Crest_CausticsDistortionTexture, _Crest_CausticsDistortionTexture_TexelSize, _Crest_CausticsDistortionScale, 1.0);
#endif // !d_Crest_WaterSurface
m_CrestNameSpace
// Get the out-scattering term.
half3 EvaluateOutScattering
(
const half3 i_Extinction,
const float3 i_PositionWS,
const half3 i_ViewWS,
const half i_Multiplier,
const float i_RawDepth,
const float i_WaterLevel
)
{
float3 positionWS = i_PositionWS;
#if !CREST_REFLECTION
// Project point onto sphere at the extinction length.
const float3 toSphere = -i_ViewWS * _Crest_VolumeExtinctionLength * i_Multiplier * _Crest_OutScatteringExtinctionFactor;
const float3 toScene = i_PositionWS - _WorldSpaceCameraPos.xyz;
positionWS = _WorldSpaceCameraPos.xyz + toSphere;
// Get closest position.
positionWS = dot(toScene, toScene) < dot(toSphere, toSphere) ? i_PositionWS : positionWS;
#endif
// Account for average extinction of light as it travels down through volume. Assume flat water as anything
// else would be expensive.
float waterDepth = max(0.0, (i_WaterLevel - positionWS.y));
#if CREST_REFLECTION
waterDepth *= 2.0;
if (i_RawDepth == 0.0) waterDepth = _Crest_VolumeExtinctionLength * i_Multiplier;
#else
// Full strength seems too extreme. Third strength seems reasonable.
waterDepth *= _Crest_OutScatteringFactor;
#endif
const float3 outScatteringTerm = exp(-i_Extinction * waterDepth);
// Transition between the Underwater Environmental Lighting (if present) and this. This will give us the
// benefit of both approaches.
return lerp(outScatteringTerm, 1.0, _Crest_UnderwaterEnvironmentalLightingWeight);
}
void GetWaterSurfaceAndUnderwaterData
(
const float4 positionCS,
const int2 positionSS,
const float rawMaskDepth,
const float mask,
inout float rawDepth,
inout bool isWaterSurface,
inout bool isUnderwater,
inout bool hasCaustics,
inout bool io_OutScatterScene,
inout bool io_ApplyLighting,
inout float sceneZ
)
{
const float rawSceneDepth = rawDepth;
hasCaustics = rawDepth != 0.0;
isWaterSurface = false;
isUnderwater = mask <= CREST_MASK_BELOW_SURFACE;
io_OutScatterScene = true;
io_ApplyLighting = true;
#if defined(d_Crest_PortalWithBackFace) || defined(d_Crest_FogBefore)
// Has back-face or is back-face.
Portal::EvaluateVolume(positionCS, positionSS, rawMaskDepth, rawSceneDepth, rawDepth, hasCaustics, isUnderwater, io_OutScatterScene, io_ApplyLighting);
#endif
// Merge water depth with scene depth.
if (rawDepth < rawMaskDepth)
{
isWaterSurface = true;
hasCaustics = false;
rawDepth = rawMaskDepth;
}
sceneZ = Utility::CrestLinearEyeDepth(rawDepth);
}
void ApplyWaterVolumeToUnderwaterFog(float4 positionCS, inout float fogDistance)
{
// TODO: could we use min here with near plane? less optimized
#if d_Crest_FogAfter
fogDistance -= Utility::CrestLinearEyeDepth(positionCS.z);
#else
// Subtract near plane.
fogDistance -= _ProjectionParams.y;
#endif
}
half3 ApplyUnderwaterEffect
(
half3 sceneColour,
const float rawDepth,
const float sceneZ,
const float fogDistance,
const half3 view,
const uint2 i_positionSS,
const float3 i_positionWS,
const bool hasCaustics,
const bool i_OutScatterScene,
const bool i_ApplyLighting,
const half i_multiplier
)
{
const bool isUnderwater = true;
float3 lightDirection; float3 lightColor;
PrimaryLight(i_positionWS, lightColor, lightDirection);
// Uniform effect calculated from camera position.
half3 volumeLight = 0.0;
half3 volumeOpacity = 1.0;
{
half3 absorption = _Crest_Absorption.xyz;
half3 scattering = _Crest_Scattering.xyz;
// We sample shadows at the camera position. Pass a user defined slice offset for smoothing out detail.
// Offset slice so that we dont get high freq detail. But never use last lod as this has crossfading.
int sliceIndex = clamp(_Crest_DataSliceOffset, 0, g_Crest_LodCount - 2);
if (g_Crest_SampleAbsorptionSimulation) absorption = Cascade::MakeAbsorption(sliceIndex).Sample(_WorldSpaceCameraPos.xz).xyz;
if (g_Crest_SampleScatteringSimulation) scattering = Cascade::MakeScattering(sliceIndex).Sample(_WorldSpaceCameraPos.xz).xyz;
absorption *= _Crest_ExtinctionMultiplier;
scattering *= _Crest_ExtinctionMultiplier;
const float waterLevel = g_Crest_WaterCenter.y + Cascade::MakeAnimatedWaves(sliceIndex).Sample(_WorldSpaceCameraPos.xz).w;
half shadow = 1.0;
{
// #if CREST_SHADOWS_ON
// Camera should be at center of LOD system so no need for blending (alpha, weights, etc). This might not be
// the case if there is large horizontal displacement, but the _Crest_DataSliceOffset should help by setting a
// large enough slice as minimum.
half2 shadowSoftHard = Cascade::MakeShadow(sliceIndex).SampleShadow(_WorldSpaceCameraPos.xz);
// Soft in red, hard in green. But hard not computed in HDRP.
shadow = 1.0 - shadowSoftHard.x;
// #endif
}
half3 ambientLighting = AmbientLight(_Crest_AmbientLighting);
const half3 extinction = VolumeExtinction(absorption, scattering);
// Out-Scattering Term.
{
const half3 outScatteringTerm = EvaluateOutScattering
(
extinction,
i_positionWS,
view,
i_multiplier,
rawDepth,
waterLevel
);
// Darken scene and light.
sceneColour *= i_OutScatterScene ? outScatteringTerm : 1.0;
#if !CREST_REFLECTION
lightColor *= outScatteringTerm;
ambientLighting *= outScatteringTerm;
#endif
}
volumeOpacity = VolumeOpacity(extinction, fogDistance);
volumeLight = VolumeLighting
(
extinction,
scattering,
_Crest_Anisotropy,
shadow,
view,
ambientLighting,
lightDirection,
lightColor,
half3(0.0, 0.0, 0.0),
_Crest_AmbientTerm,
_Crest_DirectTerm,
_Crest_SunBoost,
_Crest_ShadowsAffectsAmbientFactor
);
}
#ifndef k_DisableCaustics
if (_Crest_CausticsEnabled && hasCaustics)
{
half lightOcclusion = PrimaryLightShadows(i_positionWS, i_positionSS);
half blur = 0.0;
const uint slice0 = PositionToSliceIndex(i_positionWS.xz, 0, g_Crest_WaterScale);
#ifdef CREST_FLOW_ON
half2 flowData = Cascade::MakeFlow(slice0).SampleFlow(i_positionWS.xz);
const Flow flow = Flow::Make(flowData, g_Crest_Time);
blur = _Crest_CausticsMotionBlur;
#endif
const float4 displacement = Cascade::MakeAnimatedWaves(slice0).Sample(i_positionWS.xz);
const float surfaceHeight = displacement.y + g_Crest_WaterCenter.y + displacement.w;
sceneColour *= Caustics
(
#ifdef CREST_FLOW_ON
flow,
#endif
i_positionWS,
surfaceHeight,
lightColor,
lightDirection,
lightOcclusion,
sceneZ,
_Crest_CausticsTiledTexture,
_Crest_CausticsTextureAverage,
_Crest_CausticsStrength,
_Crest_CausticsFocalDepth,
_Crest_CausticsDepthOfField,
_Crest_CausticsDistortionTiledTexture,
_Crest_CausticsDistortionStrength,
blur,
isUnderwater
);
}
#endif
#if CREST_HDRP
volumeLight *= GetCurrentExposureMultiplier();
#endif
#ifndef k_DisableDithering
#if d_Dithering
// Increasing intensity can be required for HDRP.
volumeLight += Utility::ScreenSpaceDither(i_positionSS) * _Crest_DitheringIntensity;
#endif
#endif
if (i_ApplyLighting)
{
sceneColour = lerp(sceneColour, volumeLight, volumeOpacity);
}
return sceneColour;
}
m_CrestNameSpaceEnd
#endif // CREST_UNDERWATER_EFFECT_SHARED_INCLUDED

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: decff59e1280c4df1bd50de3e83a28a6
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#define CREST_URP 1
#define CREST_SHADERGRAPH_CONSTANTS_H
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 40ef61909a559462ab3c6dd2143a77f8
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: