修改水
This commit is contained in:
151
Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl
Normal file
151
Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl
Normal file
@@ -0,0 +1,151 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#ifndef CREST_UNDERWATER_MASK_SHARED_INCLUDED
|
||||
#define CREST_UNDERWATER_MASK_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/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
|
||||
|
||||
// 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;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
Varyings Vertex(Attributes v)
|
||||
{
|
||||
// This will work for all pipelines.
|
||||
Varyings output = (Varyings)0;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
||||
|
||||
const Cascade cascade0 = Cascade::Make(_Crest_LodIndex);
|
||||
const Cascade cascade1 = Cascade::Make(_Crest_LodIndex + 1);
|
||||
|
||||
float3 worldPos = mul(UNITY_MATRIX_M, float4(v.vertex.xyz, 1.0)).xyz;
|
||||
|
||||
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
|
||||
worldPos.xz += _WorldSpaceCameraPos.xz;
|
||||
#endif
|
||||
|
||||
// Vertex snapping and lod transition
|
||||
float lodAlpha;
|
||||
SnapAndTransitionVertLayout(_Crest_ChunkMeshScaleAlpha, cascade0, _Crest_ChunkGeometryGridWidth, worldPos, lodAlpha);
|
||||
|
||||
{
|
||||
// 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);
|
||||
// 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));
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
// Data that needs to be sampled at the undisplaced position
|
||||
if (wt_smallerLod > m_CrestSampleLodThreshold)
|
||||
{
|
||||
Cascade::MakeAnimatedWaves(_Crest_LodIndex).SampleDisplacement(positionWS_XZ_before, wt_smallerLod, worldPos);
|
||||
}
|
||||
if (wt_biggerLod > m_CrestSampleLodThreshold)
|
||||
{
|
||||
Cascade::MakeAnimatedWaves(_Crest_LodIndex + 1).SampleDisplacement(positionWS_XZ_before, wt_biggerLod, worldPos);
|
||||
}
|
||||
|
||||
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
|
||||
worldPos.xz -= _WorldSpaceCameraPos.xz;
|
||||
#endif
|
||||
|
||||
output.positionCS = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
half4 Fragment(const Varyings input, const bool i_isFrontFace)
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
|
||||
half4 result = 0.0;
|
||||
|
||||
#if (CREST_PORTALS != 0)
|
||||
#if !d_Tunnel
|
||||
bool masked = false;
|
||||
|
||||
if (m_CrestPortal)
|
||||
{
|
||||
masked = ApplyVolumeToWaterMask(input.positionCS);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (IsUnderwater(i_isFrontFace, g_Crest_ForceUnderwater))
|
||||
{
|
||||
result = (half4)_Crest_MaskBelowSurface;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (half4)CREST_MASK_ABOVE_SURFACE;
|
||||
}
|
||||
|
||||
#if (CREST_PORTALS != 0)
|
||||
#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)
|
||||
{
|
||||
result = (half4)CREST_MASK_ABOVE_SURFACE;
|
||||
}
|
||||
#else
|
||||
if (m_CrestPortal)
|
||||
{
|
||||
result *= masked ? 2 : 1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestVertex
|
||||
m_CrestFragmentWithFrontFace(half4)
|
||||
|
||||
#endif // CREST_UNDERWATER_MASK_SHARED_INCLUDED
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b891a37e4cd634b03888a64e8965920b
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,253 @@
|
||||
// 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 [_StencilRef]
|
||||
Comp [_Crest_StencilComparison]
|
||||
}
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex Vertex
|
||||
#pragma fragment Fragment
|
||||
// for VFACE
|
||||
#pragma target 3.0
|
||||
|
||||
#pragma multi_compile_local __ 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 (Depth Only)"
|
||||
Cull Off
|
||||
ColorMask 0
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex Vertex
|
||||
#pragma fragment Fragment
|
||||
// for VFACE
|
||||
#pragma target 3.0
|
||||
|
||||
#define m_Discard discard
|
||||
|
||||
#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 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]
|
||||
}
|
||||
|
||||
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" }
|
||||
|
||||
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 [_StencilRef]
|
||||
Comp [_Crest_StencilComparison]
|
||||
}
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex Vertex
|
||||
#pragma fragment Fragment
|
||||
// for VFACE
|
||||
#pragma target 3.0
|
||||
|
||||
#pragma multi_compile_local __ 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 (Depth Only)"
|
||||
Cull Off
|
||||
ColorMask 0
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex Vertex
|
||||
#pragma fragment Fragment
|
||||
// for VFACE
|
||||
#pragma target 3.0
|
||||
|
||||
#define m_Discard discard
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Volume/Mask.hlsl"
|
||||
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
|
||||
|
||||
Stencil
|
||||
{
|
||||
Ref [_StencilRef]
|
||||
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
|
||||
{
|
||||
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 [_StencilRef]
|
||||
Comp [_Crest_StencilComparison]
|
||||
}
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex Vertex
|
||||
#pragma fragment Fragment
|
||||
// for VFACE
|
||||
#pragma target 3.0
|
||||
|
||||
#pragma multi_compile_local __ d_Tunnel
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "Water Surface Mask (Depth Only)"
|
||||
Cull Off
|
||||
ColorMask 0
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex Vertex
|
||||
#pragma fragment Fragment
|
||||
// for VFACE
|
||||
#pragma target 3.0
|
||||
|
||||
#define m_Discard discard
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex Vertex
|
||||
#pragma fragment Fragment
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
#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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: edb653e62cc924b99b0a1086ffb39be7
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,61 @@
|
||||
// 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
|
||||
|
||||
// Built-in will not handle this for us unlike other RPs.
|
||||
#pragma multi_compile __ STEREO_INSTANCING_ON
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Core.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)];
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08549c36146ad4899a07193754b21ea2
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
// 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"
|
||||
#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;
|
||||
|
||||
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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f5a4cb92ecd4468e84893f8257be090
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,162 @@
|
||||
// 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"
|
||||
|
||||
#ifndef SUPPORTS_FOVEATED_RENDERING_NON_UNIFORM_RASTER
|
||||
#define FoveatedRemapLinearToNonUniform(uv) uv
|
||||
#endif
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
#if CREST_WATER_VOLUME
|
||||
float3 positionOS : POSITION;
|
||||
#else
|
||||
uint id : SV_VertexID;
|
||||
#endif
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
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 CREST_WATER_VOLUME
|
||||
// Use actual geometry instead of full screen triangle.
|
||||
output.positionCS = TransformObjectToHClip(input.positionOS);
|
||||
#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;
|
||||
float mask = LOAD_TEXTURE2D_X(_Crest_WaterMaskTexture, positionSS).x;
|
||||
|
||||
const float2 uv = FoveatedRemapLinearToNonUniform(positionSS / _ScreenSize.xy);
|
||||
|
||||
#if !_DEBUG_VISUALIZE_MASK
|
||||
#if !d_Meniscus
|
||||
// Preserve alpha channel.
|
||||
if (mask > CREST_MASK_BELOW_SURFACE)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float rawDepth = LoadCameraDepth(positionSS);
|
||||
half3 sceneColour = LOAD_TEXTURE2D_X(_Crest_CameraColorTexture, positionSS).rgb;
|
||||
const float rawMaskDepth = LOAD_TEXTURE2D_X(_Crest_WaterMaskDepthTexture, positionSS).x;
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
#if !_DEBUG_VISUALIZE_MASK
|
||||
#if d_Meniscus
|
||||
// Preserve alpha channel.
|
||||
if (!isUnderwater && wt >= 1.0)
|
||||
{
|
||||
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
|
||||
|
||||
#if _DEBUG_VISUALIZE_MASK
|
||||
return DebugRenderWaterMask(isWaterSurface, isUnderwater, mask, sceneColour);
|
||||
#endif
|
||||
|
||||
if (isUnderwater)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return half4(wt * sceneColour, 1.0);
|
||||
}
|
||||
|
||||
half4 FragmentPlanarReflections(Varyings input)
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
||||
|
||||
const uint2 positionSS = input.positionCS.xy;
|
||||
float depth = LoadCameraDepth(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 = LOAD_TEXTURE2D_X(_Crest_CameraColorTexture, positionSS).rgb;
|
||||
|
||||
// Calculate position and account for possible NaNs discovered during testing.
|
||||
float3 positionWS;
|
||||
{
|
||||
float4 positionCS = ComputeClipSpacePosition(positionSS / _ScreenSize.xy, 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);
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2636ae353ea154204861c022e68003df
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,735 @@
|
||||
// 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
|
||||
|
||||
[Space(10)]
|
||||
|
||||
[Toggle(d_Meniscus)]
|
||||
_Crest_MeniscusEnabled("Meniscus", Integer) = 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_Meniscus
|
||||
#pragma shader_feature_local_fragment __ d_Dithering
|
||||
|
||||
#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" }
|
||||
|
||||
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" }
|
||||
|
||||
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 "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 "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 "Volume: Front Face (2D)"
|
||||
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 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 "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 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 "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 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 "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 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 "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 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 "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 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
|
||||
{
|
||||
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 "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 "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 "Volume: Front Face (2D)"
|
||||
Cull Back
|
||||
ZTest LEqual
|
||||
|
||||
HLSLPROGRAM
|
||||
#include_with_pragmas "UnderwaterBIRP.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 "UnderwaterBIRP.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 "UnderwaterBIRP.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 "UnderwaterBIRP.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 "UnderwaterBIRP.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 "UnderwaterBIRP.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
|
||||
}
|
||||
}
|
||||
CustomEditor "WaveHarmonic.Crest.Editor.CustomShaderGUI"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 034b985bd9c344992af148e26d2cdb24
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#define BUILTIN_TARGET_API 1
|
||||
|
||||
#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"
|
||||
#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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 765d2ceee80af4bd5a637f79488a3433
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
// 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"
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b3db686f3a7746698c6193fcdc22ff2
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,485 @@
|
||||
// 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"
|
||||
|
||||
#if defined(CREST_WATER_VOLUME) || defined(CREST_WATER_VOLUME_FULLSCREEN)
|
||||
#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/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
|
||||
//
|
||||
|
||||
half4 _Crest_Absorption;
|
||||
half4 _Crest_Scattering;
|
||||
half _Crest_Anisotropy;
|
||||
|
||||
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;
|
||||
|
||||
half _Crest_DirectTerm;
|
||||
half _Crest_AmbientTerm;
|
||||
half _Crest_ShadowsAffectsAmbientFactor;
|
||||
|
||||
//
|
||||
// Volume Only
|
||||
//
|
||||
|
||||
float2 _Crest_HorizonNormal;
|
||||
|
||||
// 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_WaterMaskTexture);
|
||||
TEXTURE2D_X(_Crest_WaterMaskDepthTexture);
|
||||
TEXTURE2D_X(_Crest_CameraColorTexture);
|
||||
|
||||
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);
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
float LinearToDeviceDepth(float linearDepth, float4 zBufferParam)
|
||||
{
|
||||
//linear = 1.0 / (zBufferParam.z * device + zBufferParam.w);
|
||||
float device = (1.0 / linearDepth - zBufferParam.w) / zBufferParam.z;
|
||||
return device;
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
#else
|
||||
// Dummy value.
|
||||
const float scale = 0.0;
|
||||
#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;
|
||||
}
|
||||
|
||||
void GetWaterSurfaceAndUnderwaterData
|
||||
(
|
||||
const float4 positionCS,
|
||||
const int2 positionSS,
|
||||
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 float sceneZ
|
||||
)
|
||||
{
|
||||
const float rawSceneDepth = rawDepth;
|
||||
hasCaustics = rawDepth != 0.0;
|
||||
isWaterSurface = false;
|
||||
isUnderwater = mask <= CREST_MASK_BELOW_SURFACE;
|
||||
hasMeniscus = true;
|
||||
rawMeniscusDepth = positionCS.z;
|
||||
|
||||
#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;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
sceneZ = Utility::CrestLinearEyeDepth(rawDepth);
|
||||
}
|
||||
|
||||
void ApplyWaterVolumeToUnderwaterFogAndMeniscus(float4 positionCS, const float meniscusRawDepth, inout float fogDistance, inout float meniscusDepth)
|
||||
{
|
||||
#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;
|
||||
#else
|
||||
float depth = Utility::CrestLinearEyeDepth(meniscusRawDepth);
|
||||
// Meniscus is rendered at the boundary so use the geometry z.
|
||||
meniscusDepth = depth;
|
||||
#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 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;
|
||||
|
||||
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 = _Crest_AmbientLighting;
|
||||
#if CREST_HDRP
|
||||
ApplyIndirectLightingMultiplier(ambientLighting);
|
||||
#endif
|
||||
|
||||
// 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);
|
||||
|
||||
// Darken scene and light.
|
||||
sceneColour *= outScatteringTerm;
|
||||
#if !CREST_REFLECTION
|
||||
lightColor *= outScatteringTerm;
|
||||
ambientLighting *= outScatteringTerm;
|
||||
#endif
|
||||
}
|
||||
|
||||
VolumeLighting
|
||||
(
|
||||
absorption * _Crest_ExtinctionMultiplier,
|
||||
scattering * _Crest_ExtinctionMultiplier,
|
||||
_Crest_Anisotropy,
|
||||
shadow,
|
||||
view,
|
||||
ambientLighting,
|
||||
lightDirection,
|
||||
lightColor,
|
||||
half3(0.0, 0.0, 0.0),
|
||||
_Crest_AmbientTerm,
|
||||
_Crest_DirectTerm,
|
||||
fogDistance,
|
||||
_Crest_SunBoost,
|
||||
_Crest_ShadowsAffectsAmbientFactor,
|
||||
volumeLight,
|
||||
volumeOpacity
|
||||
);
|
||||
}
|
||||
|
||||
#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 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 += ScreenSpaceDither(i_positionSS) * _Crest_DitheringIntensity;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return lerp(sceneColour, volumeLight, volumeOpacity);
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
#endif // CREST_UNDERWATER_EFFECT_SHARED_INCLUDED
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: decff59e1280c4df1bd50de3e83a28a6
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
// 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"
|
||||
|
||||
TEXTURE2D_X(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture);
|
||||
|
||||
#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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40ef61909a559462ab3c6dd2143a77f8
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user