升级水插件

This commit is contained in:
2026-01-08 22:30:55 +08:00
parent febff82d24
commit ca68084264
415 changed files with 18138 additions and 7134 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: 557d66ce32c8ea44dba2cb2ff07dd49d
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,51 @@
// 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 STEREO_MULTIVIEW_ON
#pragma multi_compile_local _ d_KeepValue
#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);
#if d_KeepValue
// Prevent rendering inside of portals.
if (_Crest_WaterMaskTexture[COORD_TEXTURE2D_X(id.xy)] != 0)
{
return;
}
#endif
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

@@ -1,8 +1,8 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#ifndef CREST_UNDERWATER_MASK_SHARED_INCLUDED
#define CREST_UNDERWATER_MASK_SHARED_INCLUDED
#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"
@@ -18,43 +18,45 @@
#include "Packages/com.waveharmonic.crest.portals/Runtime/Shaders/Library/Portals.hlsl"
#endif
// Variable mask for when fog is applied before transparent pass and water tile might be culled.
half _Crest_MaskBelowSurface;
m_CrestNameSpace
struct Attributes
{
// The old unity macros require this name and type.
float4 vertex : POSITION;
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(Attributes v)
Varyings Vertex(const Attributes i_Input)
{
// This will work for all pipelines.
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_SETUP_INSTANCE_ID(i_Input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
const Cascade cascade0 = Cascade::Make(_Crest_LodIndex);
const Cascade cascade1 = Cascade::Make(_Crest_LodIndex + 1);
const uint slice0 = _Crest_LodIndex;
const uint slice1 = _Crest_LodIndex + 1;
float3 worldPos = mul(UNITY_MATRIX_M, float4(v.vertex.xyz, 1.0)).xyz;
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)
worldPos.xz += _WorldSpaceCameraPos.xz;
positionWS.xz += _WorldSpaceCameraPos.xz;
#endif
// Vertex snapping and lod transition
float lodAlpha;
SnapAndTransitionVertLayout(_Crest_ChunkMeshScaleAlpha, cascade0, _Crest_ChunkGeometryGridWidth, worldPos, lodAlpha);
float alpha;
SnapAndTransitionVertLayout(_Crest_ChunkMeshScaleAlpha, cascade0, _Crest_ChunkGeometryGridWidth, positionWS, alpha);
{
// Scale up by small "epsilon" to solve numerical issues. Expand slightly about tile center.
@@ -64,83 +66,82 @@ Varyings Vertex(Attributes v)
tileCenterXZ += _WorldSpaceCameraPos.xz;
#endif
const float2 cameraPositionXZ = abs(_WorldSpaceCameraPos.xz);
// Scale "epsilon" by distance from zero. There is an issue where overlaps can cause SV_IsFrontFace
// to be flipped (needs to be investigated). Gaps look bad from above surface, and overlaps look bad
// from below surface. We want to close gaps without introducing overlaps. A fixed "epsilon" will
// either not solve gaps at large distances or introduce too many overlaps at small distances. Even
// with scaling, there are still unsolvable overlaps underwater (especially at large distances).
// 100,000 (0.00001) is the maximum position before Unity warns the user of precision issues.
worldPos.xz = lerp(tileCenterXZ, worldPos.xz, lerp(1.0, 1.01, max(cameraPositionXZ.x, cameraPositionXZ.y) * 0.00001));
positionWS.xz = lerp(tileCenterXZ, positionWS.xz, lerp(1.0, 1.01, max(cameraPositionXZ.x, cameraPositionXZ.y) * 0.00001));
}
// Calculate sample weights. params.z allows shape to be faded out (used on last lod to support pop-less scale transitions)
const float wt_smallerLod = (1.0 - lodAlpha) * cascade0._Weight;
const float wt_biggerLod = (1.0 - wt_smallerLod) * cascade1._Weight;
// Sample displacement textures, add results to current world pos / normal / foam
const float2 positionWS_XZ_before = worldPos.xz;
const float weight0 = (1.0 - alpha) * cascade0._Weight;
const float weight1 = (1.0 - weight0) * cascade1._Weight;
// Data that needs to be sampled at the undisplaced position
if (wt_smallerLod > m_CrestSampleLodThreshold)
const float2 positionXZ = positionWS.xz;
// Data that needs to be sampled at the undisplaced position.
if (weight0 > m_CrestSampleLodThreshold)
{
Cascade::MakeAnimatedWaves(_Crest_LodIndex).SampleDisplacement(positionWS_XZ_before, wt_smallerLod, worldPos);
Cascade::MakeAnimatedWaves(slice0).SampleDisplacement(positionXZ, weight0, positionWS);
}
if (wt_biggerLod > m_CrestSampleLodThreshold)
if (weight1 > m_CrestSampleLodThreshold)
{
Cascade::MakeAnimatedWaves(_Crest_LodIndex + 1).SampleDisplacement(positionWS_XZ_before, wt_biggerLod, worldPos);
Cascade::MakeAnimatedWaves(slice1).SampleDisplacement(positionXZ, weight1, positionWS);
}
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
worldPos.xz -= _WorldSpaceCameraPos.xz;
positionWS.xz -= _WorldSpaceCameraPos.xz;
#endif
output.positionCS = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
output.positionCS = mul(UNITY_MATRIX_VP, float4(positionWS, 1.0));
#if d_LodInput
output.positionWS = positionWS;
#endif
return output;
}
half4 Fragment(const Varyings input, const bool i_isFrontFace)
half4 Fragment(const Varyings i_Input, const bool i_FrontFace)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i_Input);
half4 result = 0.0;
#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
bool masked = false;
if (m_CrestPortal)
{
masked = ApplyVolumeToWaterMask(input.positionCS);
Portal::EvaluateMask(i_Input.positionCS);
}
#endif
#endif
if (IsUnderwater(i_isFrontFace, g_Crest_ForceUnderwater))
if (IsUnderWater(i_FrontFace, g_Crest_ForceUnderwater))
{
result = (half4)_Crest_MaskBelowSurface;
result = CREST_MASK_BELOW_SURFACE;
}
else
{
result = (half4)CREST_MASK_ABOVE_SURFACE;
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 float rawFrontFaceZ = LOAD_DEPTH_TEXTURE_X(_Crest_WaterVolumeFrontFaceTexture, input.positionCS.xy);
const float rawBackFaceZ = LOAD_DEPTH_TEXTURE_X(_Crest_WaterVolumeBackFaceTexture, input.positionCS.xy);
if (rawFrontFaceZ <= 0.0 && rawBackFaceZ > 0.0)
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 = (half4)CREST_MASK_ABOVE_SURFACE;
}
#else
if (m_CrestPortal)
{
result *= masked ? 2 : 1;
result = CREST_MASK_ABOVE_SURFACE;
}
#endif
#endif
return result;
return (half4)result;
}
m_CrestNameSpaceEnd
@@ -148,4 +149,4 @@ m_CrestNameSpaceEnd
m_CrestVertex
m_CrestFragmentWithFrontFace(half4)
#endif // CREST_UNDERWATER_MASK_SHARED_INCLUDED
#endif // d_WaveHarmonic_Crest_Mask

View File

@@ -21,7 +21,7 @@ Shader "Hidden/Crest/Underwater/Water Surface Mask"
Stencil
{
Ref [_StencilRef]
Ref [_Crest_StencilReference]
Comp [_Crest_StencilComparison]
}
@@ -31,7 +31,7 @@ Shader "Hidden/Crest/Underwater/Water Surface Mask"
// for VFACE
#pragma target 3.0
#pragma multi_compile_local __ d_Tunnel
#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"
@@ -42,9 +42,8 @@ Shader "Hidden/Crest/Underwater/Water Surface Mask"
Pass
{
Name "Water Surface Mask (Depth Only)"
Name "Water Surface Mask (Negative Volume)"
Cull Off
ColorMask 0
HLSLPROGRAM
#pragma vertex Vertex
@@ -52,7 +51,9 @@ Shader "Hidden/Crest/Underwater/Water Surface Mask"
// for VFACE
#pragma target 3.0
#define m_Discard discard
#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"
@@ -63,26 +64,21 @@ Shader "Hidden/Crest/Underwater/Water Surface Mask"
Pass
{
Name "Water Horizon Mask"
Cull Off
ZWrite Off
// Horizon must be rendered first or it will overwrite the mask with incorrect values. ZTest not needed.
ZTest Always
Stencil
{
Ref [_StencilRef]
Comp [_Crest_StencilComparison]
}
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/MaskHorizon.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDHLSL
}
}
@@ -105,7 +101,7 @@ Shader "Hidden/Crest/Underwater/Water Surface Mask"
Stencil
{
Ref [_StencilRef]
Ref [_Crest_StencilReference]
Comp [_Crest_StencilComparison]
}
@@ -115,7 +111,7 @@ Shader "Hidden/Crest/Underwater/Water Surface Mask"
// for VFACE
#pragma target 3.0
#pragma multi_compile_local __ d_Tunnel
#pragma multi_compile_local_fragment __ d_Tunnel
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
@@ -125,9 +121,8 @@ Shader "Hidden/Crest/Underwater/Water Surface Mask"
Pass
{
Name "Water Surface Mask (Depth Only)"
Name "Water Surface Mask (Negative Volume)"
Cull Off
ColorMask 0
HLSLPROGRAM
#pragma vertex Vertex
@@ -135,7 +130,9 @@ Shader "Hidden/Crest/Underwater/Water Surface Mask"
// for VFACE
#pragma target 3.0
#define m_Discard discard
#define m_Return discard
#define d_Crest_NegativeVolumePass 1
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
@@ -145,25 +142,20 @@ Shader "Hidden/Crest/Underwater/Water Surface Mask"
Pass
{
Name "Water Horizon Mask"
Cull Off
ZWrite Off
// Horizon must be rendered first or it will overwrite the mask with incorrect values. ZTest not needed.
ZTest Always
Stencil
{
Ref [_StencilRef]
Comp [_Crest_StencilComparison]
}
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/MaskHorizon.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDHLSL
}
}
@@ -179,75 +171,62 @@ Shader "Hidden/Crest/Underwater/Water Surface Mask"
Stencil
{
Ref [_StencilRef]
Ref [_Crest_StencilReference]
Comp [_Crest_StencilComparison]
}
CGPROGRAM
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
// for VFACE
#pragma target 3.0
#pragma multi_compile_local __ d_Tunnel
#include "UnityCG.cginc"
#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/Library/Utility/Legacy/InputsDriven.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDCG
ENDHLSL
}
Pass
{
Name "Water Surface Mask (Depth Only)"
Name "Water Surface Mask (Negative Volume)"
Cull Off
ColorMask 0
CGPROGRAM
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
// for VFACE
#pragma target 3.0
#define m_Discard discard
#define m_Return discard
#include "UnityCG.cginc"
#define d_Crest_NegativeVolumePass 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Core.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/InputsDriven.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDCG
ENDHLSL
}
Pass
{
Name "Water Horizon Mask"
Cull Off
ZWrite Off
// Horizon must be rendered first or it will overwrite the mask with incorrect values. ZTest not needed.
ZTest Always
Name "Water Surface Data"
Cull Back
Stencil
{
Ref [_StencilRef]
Comp [_Crest_StencilComparison]
}
CGPROGRAM
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
#include "UnityCG.cginc"
#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/Library/Utility/Legacy/InputsDriven.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/MaskHorizon.hlsl"
ENDCG
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
ENDHLSL
}
}
}

View File

@@ -4,13 +4,12 @@
// 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
#pragma kernel FillMaskArtefacts _BRP
// Built-in will not handle this for us unlike other RPs.
#pragma multi_compile __ STEREO_INSTANCING_ON
#pragma multi_compile _ STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
#include "UnityCG.cginc"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Core.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/RP/Compute.hlsl"
RW_TEXTURE2D_X(float, _Crest_WaterMaskTexture);

View File

@@ -8,7 +8,6 @@
#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/Utility/Depth.hlsl"
// Driven by scripting. It is a non-linear converted from a linear 0-1 value.
float _Crest_FarPlaneOffset;

View File

@@ -3,16 +3,32 @@
#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 CREST_WATER_VOLUME
#if d_Crest_Geometry
float3 positionOS : POSITION;
#else
uint id : SV_VertexID;
@@ -23,6 +39,9 @@ struct Attributes
struct Varyings
{
float4 positionCS : SV_POSITION;
#if d_Crest_ComputeMask
float3 positionWS : TEXCOORD;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
@@ -33,9 +52,12 @@ Varyings Vertex(Attributes input)
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
#if CREST_WATER_VOLUME
#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
@@ -48,53 +70,70 @@ half4 Fragment(Varyings input)
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
uint2 positionSS = input.positionCS.xy;
float mask = LOAD_TEXTURE2D_X(_Crest_WaterMaskTexture, positionSS).x;
const float2 positionNDC = (positionSS + 0.5) / _ScreenSize.xy;
float mask = -1.0;
const float2 uv = FoveatedRemapLinearToNonUniform(positionSS / _ScreenSize.xy);
#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
#if !d_Meniscus
// Preserve alpha channel.
if (mask > CREST_MASK_BELOW_SURFACE)
{
discard;
}
#endif
#endif
#endif // !d_Crest_NoMaskColor
float rawDepth = LoadCameraDepth(positionSS);
half3 sceneColour = LOAD_TEXTURE2D_X(_Crest_CameraColorTexture, positionSS).rgb;
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; bool hasMeniscus; float sceneZ; float meniscusRawDepth;
GetWaterSurfaceAndUnderwaterData(input.positionCS, positionSS, rawMaskDepth, mask, rawDepth, meniscusRawDepth, isWaterSurface, isUnderwater, hasCaustics, hasMeniscus, sceneZ);
float wt = 1.0;
if (hasMeniscus)
{
wt = ComputeMeniscusWeight(positionSS, mask, _Crest_HorizonNormal, sceneZ);
}
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
#if d_Meniscus
// Preserve alpha channel.
if (!isUnderwater && wt >= 1.0)
if (!isUnderwater)
{
discard;
}
#endif
#endif
float fogDistance = sceneZ;
float meniscusDepth = 0.0;
#if defined(CREST_WATER_VOLUME) || defined(CREST_WATER_VOLUME_FULLSCREEN)
ApplyWaterVolumeToUnderwaterFogAndMeniscus(input.positionCS, meniscusRawDepth, fogDistance, meniscusDepth);
#endif
ApplyWaterVolumeToUnderwaterFog(input.positionCS, fogDistance);
#if _DEBUG_VISUALIZE_MASK
return DebugRenderWaterMask(isWaterSurface, isUnderwater, mask, sceneColour);
@@ -102,15 +141,16 @@ half4 Fragment(Varyings input)
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);
sceneColour = ApplyUnderwaterEffect(sceneColour, rawDepth, sceneZ, fogDistance, view, positionSS, positionWS, hasCaustics, outScatterScene, applyLighting, 1.0);
}
return half4(wt * sceneColour, 1.0);
return half4(sceneColour, 1.0);
}
half4 FragmentPlanarReflections(Varyings input)
@@ -118,7 +158,8 @@ half4 FragmentPlanarReflections(Varyings input)
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
const uint2 positionSS = input.positionCS.xy;
float depth = LoadCameraDepth(positionSS);
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)
@@ -126,12 +167,12 @@ half4 FragmentPlanarReflections(Varyings input)
return half4(_Crest_Scattering.xyz, 1.0);
}
half3 color = LOAD_TEXTURE2D_X(_Crest_CameraColorTexture, positionSS).rgb;
half3 color = SampleSceneColor(positionNDC).rgb;
// Calculate position and account for possible NaNs discovered during testing.
float3 positionWS;
{
float4 positionCS = ComputeClipSpacePosition(positionSS / _ScreenSize.xy, depth);
float4 positionCS = ComputeClipSpacePosition(positionNDC, depth);
float4 hpositionWS = mul(UNITY_MATRIX_I_VP, positionCS);
// w is sometimes zero when using oblique projection.
@@ -146,7 +187,7 @@ half4 FragmentPlanarReflections(Varyings input)
const half3 view = GetWorldSpaceNormalizeViewDir(positionWS);
const bool hasCaustics = depth > 0.0;
color = ApplyUnderwaterEffect(color, depth, 0.0, 0.0, view, positionSS, positionWS, hasCaustics);
color = ApplyUnderwaterEffect(color, depth, 0.0, 0.0, view, positionSS, positionWS, hasCaustics, true, true, 1.0);
return half4(color, 1.0);
}

View File

@@ -1,4 +1,4 @@
// Crest Water System
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
Shader "Crest/Underwater"
@@ -17,11 +17,6 @@ Shader "Crest/Underwater"
_Crest_DitheringEnabled("Dithering", Integer) = 1
_Crest_DitheringIntensity("Dithering Intensity", Range(0, 10)) = 1
[Space(10)]
[Toggle(d_Meniscus)]
_Crest_MeniscusEnabled("Meniscus", Integer) = 1
[Header(Advanced)]
[Space(6)]
@@ -68,9 +63,13 @@ Shader "Crest/Underwater"
// Also on the water shader.
#pragma multi_compile_local_fragment __ CREST_FLOW_ON
#pragma shader_feature_local_fragment __ d_Meniscus
#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
@@ -84,239 +83,17 @@ Shader "Crest/Underwater"
Tags { "RenderPipeline"="HDRenderPipeline" }
ZWrite Off
Blend Off
Pass
{
Name "Full Screen"
Cull Off
ZTest Always
HLSLPROGRAM
#include_with_pragmas "UnderwaterHDRP.hlsl"
// Both "__" and "_FULL_SCREEN_EFFECT" are fullscreen triangles. The latter only denotes an optimisation of
// whether to skip the horizon calculation.
#pragma multi_compile_local_fragment __ _FULL_SCREEN_EFFECT
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
Name "Reflection"
Cull Off
ZTest Always
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 "Volume: Front Face (2D)"
Cull Back
ZTest LEqual
HLSLPROGRAM
#include_with_pragmas "UnderwaterHDRP.hlsl"
#define CREST_WATER_VOLUME 1
#define CREST_WATER_VOLUME_FRONT_FACE 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 "Volume: Front Face (3D)"
Cull Back
ZTest LEqual
HLSLPROGRAM
#include_with_pragmas "UnderwaterHDRP.hlsl"
#define CREST_WATER_VOLUME 1
#define CREST_WATER_VOLUME_HAS_BACKFACE 1
#define CREST_WATER_VOLUME_FRONT_FACE 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 "Volume: Front 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"
#define CREST_WATER_VOLUME 1
#define CREST_WATER_VOLUME_HAS_BACKFACE 1
#define CREST_WATER_VOLUME_FRONT_FACE 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 "Volume: Back Face"
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 CREST_WATER_VOLUME 1
#define CREST_WATER_VOLUME_BACK_FACE 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 "Volume: Scene (Full Screen)"
Cull Back
ZTest Always
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 CREST_WATER_VOLUME_FULLSCREEN 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
ENDHLSL
}
Pass
{
PackageRequirements
{
"com.waveharmonic.crest.portals"
}
Name "Volume: Negative (Full Screen)"
Cull Off
ZTest Always
HLSLPROGRAM
#include_with_pragmas "UnderwaterHDRP.hlsl"
#define CREST_WATER_VOLUME_FULLSCREEN 1
#define CREST_WATER_VOLUME_NEGATIVE 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" }
Cull Off
ZTest Always
ZWrite Off
Pass
{
Name "Full Screen"
Cull Off
ZTest Always
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"
// Both "__" and "_FULL_SCREEN_EFFECT" are fullscreen triangles. The latter only denotes an optimisation of
// whether to skip the horizon calculation.
#pragma multi_compile_local_fragment __ _FULL_SCREEN_EFFECT
#include_with_pragmas "UnderwaterHDRP.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
@@ -326,14 +103,10 @@ Shader "Crest/Underwater"
Pass
{
Name "Reflection"
Cull Off
ZTest Always
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_with_pragmas "UnderwaterHDRP.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment FragmentPlanarReflections
@@ -348,17 +121,19 @@ Shader "Crest/Underwater"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Volume: Front Face (2D)"
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"
#include_with_pragmas "UnderwaterHDRP.hlsl"
#define CREST_WATER_VOLUME 1
#define CREST_WATER_VOLUME_FRONT_FACE 1
#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
@@ -373,18 +148,18 @@ Shader "Crest/Underwater"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Volume: Front Face (3D)"
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"
#include_with_pragmas "UnderwaterHDRP.hlsl"
#define CREST_WATER_VOLUME 1
#define CREST_WATER_VOLUME_HAS_BACKFACE 1
#define CREST_WATER_VOLUME_FRONT_FACE 1
#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
@@ -399,7 +174,8 @@ Shader "Crest/Underwater"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Volume: Front Face (Fly-Through)"
Name "Fog After To Back-Face (Fly-Through)"
Cull Back
ZTest LEqual
@@ -414,13 +190,14 @@ Shader "Crest/Underwater"
}
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_with_pragmas "UnderwaterHDRP.hlsl"
#define CREST_WATER_VOLUME 1
#define CREST_WATER_VOLUME_HAS_BACKFACE 1
#define CREST_WATER_VOLUME_FRONT_FACE 1
#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
@@ -436,7 +213,8 @@ Shader "Crest/Underwater"
}
// fog to the back face (and in effect anything behind it). No caustics.
Name "Volume: Back Face"
Name "Fog Before (Fly-Through)"
Cull Front
ZTest LEqual
@@ -451,12 +229,13 @@ Shader "Crest/Underwater"
}
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_with_pragmas "UnderwaterHDRP.hlsl"
#define CREST_WATER_VOLUME 1
#define CREST_WATER_VOLUME_BACK_FACE 1
#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
@@ -471,9 +250,8 @@ Shader "Crest/Underwater"
}
// When inside a volume, this pass will render to the scene within the volume.
Name "Volume: Scene (Full Screen)"
Cull Back
ZTest Always
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
@@ -487,11 +265,9 @@ Shader "Crest/Underwater"
}
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_with_pragmas "UnderwaterHDRP.hlsl"
#define CREST_WATER_VOLUME_FULLSCREEN 1
#define d_Crest_Portal 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
@@ -505,17 +281,16 @@ Shader "Crest/Underwater"
"com.waveharmonic.crest.portals"
}
Name "Volume: Negative (Full Screen)"
Cull Off
ZTest Always
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"
#include_with_pragmas "UnderwaterHDRP.hlsl"
#define CREST_WATER_VOLUME_FULLSCREEN 1
#define CREST_WATER_VOLUME_NEGATIVE 1
#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
@@ -525,21 +300,257 @@ Shader "Crest/Underwater"
SubShader
{
PackageRequirements
{
"com.unity.render-pipelines.universal"
}
Tags { "RenderPipeline"="UniversalPipeline" }
Blend Off
Cull Off
ZTest Always
ZWrite Off
Pass
{
Name "Full Screen"
Cull Off
ZTest Always
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
// Both "__" and "_FULL_SCREEN_EFFECT" are fullscreen triangles. The latter only denotes an optimisation of
// whether to skip the horizon calculation.
#pragma multi_compile_local_fragment __ _FULL_SCREEN_EFFECT
#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
@@ -549,8 +560,6 @@ Shader "Crest/Underwater"
Pass
{
Name "Reflection"
Cull Off
ZTest Always
HLSLPROGRAM
#define CREST_REFLECTION 1
@@ -569,15 +578,19 @@ Shader "Crest/Underwater"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Volume: Front Face (2D)"
Name "Fog After"
Cull Back
ZTest LEqual
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#define CREST_WATER_VOLUME 1
#define CREST_WATER_VOLUME_FRONT_FACE 1
#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
@@ -592,16 +605,18 @@ Shader "Crest/Underwater"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Volume: Front Face (3D)"
Name "Fog After To Back-Face"
Cull Back
ZTest LEqual
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#define CREST_WATER_VOLUME 1
#define CREST_WATER_VOLUME_HAS_BACKFACE 1
#define CREST_WATER_VOLUME_FRONT_FACE 1
#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
@@ -616,7 +631,8 @@ Shader "Crest/Underwater"
}
// Only adds fog to the front face and in effect anything behind it.
Name "Volume: Front Face (Fly-Through)"
Name "Fog After To Back-Face (Fly-Through)"
Cull Back
ZTest LEqual
@@ -633,9 +649,11 @@ Shader "Crest/Underwater"
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#define CREST_WATER_VOLUME 1
#define CREST_WATER_VOLUME_HAS_BACKFACE 1
#define CREST_WATER_VOLUME_FRONT_FACE 1
#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
@@ -651,7 +669,8 @@ Shader "Crest/Underwater"
}
// fog to the back face (and in effect anything behind it). No caustics.
Name "Volume: Back Face"
Name "Fog Before (Fly-Through)"
Cull Front
ZTest LEqual
@@ -668,8 +687,14 @@ Shader "Crest/Underwater"
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#define CREST_WATER_VOLUME 1
#define CREST_WATER_VOLUME_BACK_FACE 1
#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
@@ -684,9 +709,8 @@ Shader "Crest/Underwater"
}
// When inside a volume, this pass will render to the scene within the volume.
Name "Volume: Scene (Full Screen)"
Cull Back
ZTest Always
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
@@ -702,7 +726,7 @@ Shader "Crest/Underwater"
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#define CREST_WATER_VOLUME_FULLSCREEN 1
#define d_Crest_Portal 1
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Underwater.hlsl"
#pragma fragment Fragment
@@ -716,15 +740,16 @@ Shader "Crest/Underwater"
"com.waveharmonic.crest.portals"
}
Name "Volume: Negative (Full Screen)"
Cull Off
ZTest Always
Name "Full Screen (Negative)"
HLSLPROGRAM
#include_with_pragmas "UnderwaterBIRP.hlsl"
#define CREST_WATER_VOLUME_FULLSCREEN 1
#define CREST_WATER_VOLUME_NEGATIVE 1
#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

View File

@@ -6,23 +6,16 @@
#define CREST_BIRP 1
#define CREST_SHADERGRAPH_CONSTANTS_H
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/Shims.hlsl"
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Core.hlsl"
#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.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/InputsDriven.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Common.hlsl"
TEXTURE2D_X(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture);
m_CrestNameSpace
float LoadCameraDepth(uint2 pixelCoords)
{
return LOAD_TEXTURE2D_X(_CameraDepthTexture, pixelCoords).r;
}
m_CrestNameSpaceEnd
#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

@@ -16,3 +16,4 @@
#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

@@ -11,8 +11,9 @@
#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 defined(CREST_WATER_VOLUME) || defined(CREST_WATER_VOLUME_FULLSCREEN)
#if d_Crest_Portal
#include "Packages/com.waveharmonic.crest.portals/Runtime/Shaders/Library/Portals.hlsl"
#endif
@@ -20,6 +21,7 @@
#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"
@@ -31,10 +33,16 @@ 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;
@@ -48,16 +56,12 @@ half _Crest_CausticsMotionBlur;
float4 _Crest_CausticsTexture_TexelSize;
float4 _Crest_CausticsDistortionTexture_TexelSize;
half _Crest_DirectTerm;
half _Crest_AmbientTerm;
half _Crest_ShadowsAffectsAmbientFactor;
#endif // !d_Crest_WaterSurface
//
// Volume Only
//
float2 _Crest_HorizonNormal;
// Out-scattering. Driven by the Water Renderer and Underwater Environmental Lighting.
float _Crest_VolumeExtinctionLength;
float _Crest_UnderwaterEnvironmentalLightingWeight;
@@ -73,9 +77,10 @@ int _Crest_DataSliceOffset;
half _Crest_DitheringIntensity;
CBUFFER_END
TEXTURE2D_X(_Crest_WaterMaskTexture);
TEXTURE2D_X(_Crest_WaterMaskDepthTexture);
TEXTURE2D_X(_Crest_CameraColorTexture);
#ifndef d_Crest_WaterSurface
TEXTURE2D_X(_Crest_WaterMaskTexture);
TEXTURE2D(_Crest_CausticsTexture);
SAMPLER(sampler_Crest_CausticsTexture);
@@ -87,118 +92,50 @@ 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
float LinearToDeviceDepth(float linearDepth, float4 zBufferParam)
// 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
)
{
//linear = 1.0 / (zBufferParam.z * device + zBufferParam.w);
float device = (1.0 / linearDepth - zBufferParam.w) / zBufferParam.z;
return device;
}
float3 positionWS = i_PositionWS;
#if d_Dithering
// Adapted from:
// https://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf
float3 ScreenSpaceDither(const float2 i_ScreenPosition)
{
// Iestyn's RGB dither (7 asm instructions) from Portal 2 X360, slightly modified for VR.
float3 dither = dot(float2(171.0, 231.0), i_ScreenPosition.xy);
dither.rgb = frac(dither.rgb / float3(103.0, 71.0, 97.0)) - float3(0.5, 0.5, 0.5);
return (dither.rgb / 255.0);
}
#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
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);
}
}
// 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));
float4 DebugRenderStencil(float3 sceneColour)
{
float3 stencil = 1.0;
#if CREST_WATER_VOLUME_FRONT_FACE
stencil = float3(1.0, 0.0, 0.0);
#elif CREST_WATER_VOLUME_BACK_FACE
stencil = float3(0.0, 1.0, 0.0);
#elif CREST_WATER_VOLUME_FULLSCREEN
stencil = float3(0.0, 0.0, 1.0);
#endif
return float4(sceneColour * stencil, 1.0);
}
float MeniscusSampleWaterMask(const float mask, const int2 positionSS, const float2 offset, const float magnitude, const float scale)
{
float2 uv = positionSS + offset * magnitude
#if defined(CREST_WATER_VOLUME) || defined(CREST_WATER_VOLUME_FULLSCREEN)
* scale
#endif
;
float newMask = LOAD_TEXTURE2D_X(_Crest_WaterMaskTexture, uv).r;
#if CREST_UNDERWATER_BEFORE_TRANSPARENT
// Normalize mask.
newMask = clamp(newMask, -1.0, 1.0);
#endif
#if CREST_WATER_VOLUME
// No mask means no underwater effect so ignore the value.
return (newMask == CREST_MASK_NONE ? mask : newMask);
#endif
return newMask;
}
half ComputeMeniscusWeight(const int2 positionSS, float mask, const float2 horizonNormal, const float meniscusDepth)
{
float weight = 1.0;
#if d_Meniscus
#if !_FULL_SCREEN_EFFECT
#if CREST_UNDERWATER_BEFORE_TRANSPARENT
// Normalize mask.
mask = clamp(mask, -1.0, 1.0);
#endif
// Render meniscus by checking the mask along the horizon normal which is flipped using the surface normal from
// mask. Adding the mask value will flip the UV when mask is below surface.
float2 offset = (float2)-mask * horizonNormal;
float multiplier = 0.9;
#if defined(CREST_WATER_VOLUME) || defined(CREST_WATER_VOLUME_FULLSCREEN)
// The meniscus at the boundary can be at a distance. We need to scale the offset as 1 pixel at a distance is much
// larger than 1 pixel up close.
const float scale = 1.0 - saturate(meniscusDepth / MENISCUS_MAXIMUM_DISTANCE);
// Exit early.
if (scale == 0.0)
{
return 1.0;
}
#if CREST_REFLECTION
waterDepth *= 2.0;
if (i_RawDepth == 0.0) waterDepth = _Crest_VolumeExtinctionLength * i_Multiplier;
#else
// Dummy value.
const float scale = 0.0;
// Full strength seems too extreme. Third strength seems reasonable.
waterDepth *= _Crest_OutScatteringFactor;
#endif
// Sample three pixels along the normal. If the sample is different than the current mask, apply meniscus.
// Offset must be added to positionSS as floats.
weight *= (MeniscusSampleWaterMask(mask, positionSS, offset, 1.0, scale) != mask) ? multiplier : 1.0;
weight *= (MeniscusSampleWaterMask(mask, positionSS, offset, 2.0, scale) != mask) ? multiplier : 1.0;
weight *= (MeniscusSampleWaterMask(mask, positionSS, offset, 3.0, scale) != mask) ? multiplier : 1.0;
#endif // _FULL_SCREEN_EFFECT
#endif // d_Meniscus
return weight;
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
@@ -208,11 +145,11 @@ void GetWaterSurfaceAndUnderwaterData
const float rawMaskDepth,
const float mask,
inout float rawDepth,
inout float rawMeniscusDepth,
inout bool isWaterSurface,
inout bool isUnderwater,
inout bool hasCaustics,
inout bool hasMeniscus,
inout bool io_OutScatterScene,
inout bool io_ApplyLighting,
inout float sceneZ
)
{
@@ -220,75 +157,17 @@ void GetWaterSurfaceAndUnderwaterData
hasCaustics = rawDepth != 0.0;
isWaterSurface = false;
isUnderwater = mask <= CREST_MASK_BELOW_SURFACE;
hasMeniscus = true;
rawMeniscusDepth = positionCS.z;
io_OutScatterScene = true;
io_ApplyLighting = true;
#if defined(CREST_WATER_VOLUME_HAS_BACKFACE) || defined(CREST_WATER_VOLUME_BACK_FACE) || defined(CREST_WATER_VOLUME_NEGATIVE)
const float rawGeometryDepth =
#if CREST_WATER_VOLUME_HAS_BACKFACE
// 3D has a back face texture for the depth.
LOAD_DEPTH_TEXTURE_X(_Crest_WaterVolumeBackFaceTexture, positionSS);
#elif CREST_WATER_VOLUME_NEGATIVE
LOAD_DEPTH_TEXTURE_X(_Crest_WaterVolumeFrontFaceTexture, positionSS);
#else
// Volume is rendered using the back face so that is the depth.
positionCS.z;
#endif // CREST_WATER_VOLUME_HAS_BACKFACE
;
if ((rawMaskDepth > 0.0 && rawMaskDepth <= rawSceneDepth) || (rawGeometryDepth > 0.0 && rawGeometryDepth <= rawSceneDepth))
{
hasMeniscus = false;
}
// Use backface depth if closest.
if (rawDepth < rawGeometryDepth)
{
// Cancels out caustics.
hasCaustics = false;
rawDepth = rawGeometryDepth;
}
#if CREST_WATER_VOLUME_NEGATIVE
rawMeniscusDepth = rawGeometryDepth;
if (rawGeometryDepth == 0.0)
{
const float rawBackFaceDepth = LOAD_DEPTH_TEXTURE_X(_Crest_WaterVolumeBackFaceTexture, positionSS);
// We are in the negative volume. Already handled by front face.
if (rawBackFaceDepth > 0.0)
{
if (rawBackFaceDepth <= rawSceneDepth)
{
hasMeniscus = false;
}
isUnderwater = false;
}
}
#endif // CREST_WATER_VOLUME_NEGATIVE
#endif // CREST_WATER_VOLUME
#if CREST_WATER_VOLUME_FRONT_FACE
// If negative volume, we keep the mask intact, and just mark it.
if (mask >= CREST_MASK_ABOVE_SURFACE_KEPT)
{
isUnderwater = true;
}
else if (mask <= CREST_MASK_BELOW_SURFACE_KEPT)
{
isUnderwater = false;
}
#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)
{
#if CREST_UNDERWATER_BEFORE_TRANSPARENT
// Apply fog to culled tiles otherwise there will be no fog as water shader can only fog enabled tiles. And
// only apply fog to culled tiles otherwise it will be fogged twice (second by water shader).
isUnderwater = mask <= CREST_MASK_BELOW_SURFACE_CULLED;
#endif
isWaterSurface = true;
hasCaustics = false;
rawDepth = rawMaskDepth;
@@ -297,21 +176,19 @@ void GetWaterSurfaceAndUnderwaterData
sceneZ = Utility::CrestLinearEyeDepth(rawDepth);
}
void ApplyWaterVolumeToUnderwaterFogAndMeniscus(float4 positionCS, const float meniscusRawDepth, inout float fogDistance, inout float meniscusDepth)
void ApplyWaterVolumeToUnderwaterFog(float4 positionCS, inout float fogDistance)
{
#if CREST_WATER_VOLUME_FRONT_FACE
float depth = Utility::CrestLinearEyeDepth(positionCS.z);
// Meniscus is rendered at the boundary so use the geometry z.
meniscusDepth = depth;
fogDistance -= depth;
// TODO: could we use min here with near plane? less optimized
#if d_Crest_FogAfter
fogDistance -= Utility::CrestLinearEyeDepth(positionCS.z);
#else
float depth = Utility::CrestLinearEyeDepth(meniscusRawDepth);
// Meniscus is rendered at the boundary so use the geometry z.
meniscusDepth = depth;
// Subtract near plane.
fogDistance -= _ProjectionParams.y;
#endif
}
half3 ApplyUnderwaterEffect(
half3 ApplyUnderwaterEffect
(
half3 sceneColour,
const float rawDepth,
const float sceneZ,
@@ -319,8 +196,12 @@ half3 ApplyUnderwaterEffect(
const half3 view,
const uint2 i_positionSS,
const float3 i_positionWS,
const bool hasCaustics
) {
const bool hasCaustics,
const bool i_OutScatterScene,
const bool i_ApplyLighting,
const half i_multiplier
)
{
const bool isUnderwater = true;
float3 lightDirection; float3 lightColor;
@@ -340,6 +221,9 @@ half3 ApplyUnderwaterEffect(
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;
@@ -354,55 +238,35 @@ half3 ApplyUnderwaterEffect(
// #endif
}
half3 ambientLighting = _Crest_AmbientLighting;
#if CREST_HDRP
ApplyIndirectLightingMultiplier(ambientLighting);
#endif
half3 ambientLighting = AmbientLight(_Crest_AmbientLighting);
const half3 extinction = VolumeExtinction(absorption, scattering);
// Out-Scattering Term.
{
float3 positionWS = i_positionWS;
#if !CREST_REFLECTION
// Project point onto sphere at the extinction length.
float3 toSphere = -view * _Crest_VolumeExtinctionLength * _Crest_OutScatteringExtinctionFactor;
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.
half3 extinction = (absorption + scattering) * _Crest_ExtinctionMultiplier;
float waterDepth = max(0.0, (waterLevel - positionWS.y));
#if CREST_REFLECTION
waterDepth *= 2.0;
if (rawDepth == 0.0) waterDepth = _Crest_VolumeExtinctionLength;
#else
// Full strength seems too extreme. Third strength seems reasonable.
waterDepth *= _Crest_OutScatteringFactor;
#endif
float3 outScatteringTerm = exp(-extinction * waterDepth);
// Transition between the Underwater Environmental Lighting (if present) and this. This will give us the
// benefit of both approaches.
outScatteringTerm = lerp(outScatteringTerm, 1.0, _Crest_UnderwaterEnvironmentalLightingWeight);
const half3 outScatteringTerm = EvaluateOutScattering
(
extinction,
i_positionWS,
view,
i_multiplier,
rawDepth,
waterLevel
);
// Darken scene and light.
sceneColour *= outScatteringTerm;
sceneColour *= i_OutScatterScene ? outScatteringTerm : 1.0;
#if !CREST_REFLECTION
lightColor *= outScatteringTerm;
ambientLighting *= outScatteringTerm;
#endif
}
VolumeLighting
volumeOpacity = VolumeOpacity(extinction, fogDistance);
volumeLight = VolumeLighting
(
absorption * _Crest_ExtinctionMultiplier,
scattering * _Crest_ExtinctionMultiplier,
extinction,
scattering,
_Crest_Anisotropy,
shadow,
view,
@@ -412,23 +276,15 @@ half3 ApplyUnderwaterEffect(
half3(0.0, 0.0, 0.0),
_Crest_AmbientTerm,
_Crest_DirectTerm,
fogDistance,
_Crest_SunBoost,
_Crest_ShadowsAffectsAmbientFactor,
volumeLight,
volumeOpacity
_Crest_ShadowsAffectsAmbientFactor
);
}
#ifndef k_DisableCaustics
if (_Crest_CausticsEnabled && hasCaustics)
{
float3 position = i_positionWS;
#if CREST_BIRP
position = float3(i_positionSS, 0);
#endif
half lightOcclusion = PrimaryLightShadows(position);
half lightOcclusion = PrimaryLightShadows(i_positionWS, i_positionSS);
half blur = 0.0;
const uint slice0 = PositionToSliceIndex(i_positionWS.xz, 0, g_Crest_WaterScale);
@@ -473,11 +329,16 @@ half3 ApplyUnderwaterEffect(
#ifndef k_DisableDithering
#if d_Dithering
// Increasing intensity can be required for HDRP.
volumeLight += ScreenSpaceDither(i_positionSS) * _Crest_DitheringIntensity;
volumeLight += Utility::ScreenSpaceDither(i_positionSS) * _Crest_DitheringIntensity;
#endif
#endif
return lerp(sceneColour, volumeLight, volumeOpacity);
if (i_ApplyLighting)
{
sceneColour = lerp(sceneColour, volumeLight, volumeOpacity);
}
return sceneColour;
}
m_CrestNameSpaceEnd

View File

@@ -10,17 +10,7 @@
#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"
TEXTURE2D_X(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture);
#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"
m_CrestNameSpace
// Shim as HDRP uses this.
float LoadCameraDepth(uint2 pixelCoords)
{
return LOAD_TEXTURE2D_X(_CameraDepthTexture, pixelCoords).r;
}
m_CrestNameSpaceEnd