还原水插件

This commit is contained in:
2026-03-05 00:14:42 +08:00
parent 0de35591e7
commit e82f2ea6b7
270 changed files with 2773 additions and 12445 deletions

View File

@@ -1,8 +1,6 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestExecute
#include "HLSLSupport.cginc"

View File

@@ -1,8 +1,6 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestTransferWaves
#pragma multi_compile_local __ d_Texture d_TextureBlend
@@ -13,7 +11,6 @@
#include "HLSLSupport.cginc"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Filtering.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"
@@ -35,8 +32,6 @@ float _Crest_RespectShallowWaterAttenuation;
float _Crest_MaximumAttenuationDepth;
float _Crest_WaveResolutionMultiplier;
float _Crest_TransitionalWavelengthThreshold;
uint _Crest_Resolution;
bool _Crest_SeaLevelOnly;
// Texture
#if d_Texture
@@ -65,8 +60,6 @@ void TransferWaves(uint3 id)
const uint last = parameters.y;
const half transition = parameters.w;
const uint2 resolution = uint2(_Crest_Resolution, _Crest_Resolution);
#if !d_TextureBlend
// Additive only. All wavelengths filtered out for this LOD so nothing to do.
if (parameters.x < 0 || parameters.y < 0)
@@ -161,12 +154,11 @@ void TransferWaves(uint3 id)
axisZ1.x = -axisX1.y; axisZ1.y = axisX1.x;
}
#else
const float2 positionWaves = float2(dot(positionWS, _Crest_AxisX), dot(positionWS, float2(-_Crest_AxisX.y, _Crest_AxisX.x)));
#endif // d_Texture
const half level = Cascade::MakeLevel(slice0).SampleLevel(positionWS);
const half depth = Cascade::MakeDepth(slice0).SampleSignedDepthFromSeaLevel(positionWS) + level;
const half depth = Cascade::MakeDepth(slice0).SampleSignedDepthFromSeaLevel(positionWS) +
Cascade::MakeLevel(slice0).SampleLevel(positionWS);
half3 _displacement = 0.0;
@@ -225,8 +217,8 @@ void TransferWaves(uint3 id)
const float2 uv1 = float2(dot(positionScaledWS, axisX1), dot(positionScaledWS, axisZ1));
// Sample displacement, rotate into frame.
const float3 displacement0 = Utility::SampleBicubicRepeat(_Crest_WaveBuffer, uv0, resolution, waveBufferIndex).xyz;
const float3 displacement1 = Utility::SampleBicubicRepeat(_Crest_WaveBuffer, uv1, resolution, waveBufferIndex).xyz;
float3 displacement0 = _Crest_WaveBuffer.SampleLevel(sampler_Crest_linear_repeat, float3(uv0, waveBufferIndex), 0).xyz;
float3 displacement1 = _Crest_WaveBuffer.SampleLevel(sampler_Crest_linear_repeat, float3(uv1, waveBufferIndex), 0).xyz;
float3 displacement = lerp(displacement0, displacement1, t);
displacement.xz = displacement.x * axis + displacement.z * float2(-axis.y, axis.x);
@@ -235,9 +227,7 @@ void TransferWaves(uint3 id)
#else // !d_Texture
// Sample displacement, rotate into frame defined by global wind direction.
// Hardware bilinear produces small noise artifacts. Custom bilinear solves that,
// but we still get texel artifacts that show up in normals, so use bicubic.
float3 displacement = Utility::SampleBicubicRepeat(_Crest_WaveBuffer, positionWaves / waveBufferSize, resolution, waveBufferIndex).xyz;
half3 displacement = _Crest_WaveBuffer.SampleLevel(sampler_Crest_linear_repeat, float3(positionWaves / waveBufferSize, waveBufferIndex), 0).xyz;
displacement.xz = displacement.x * _Crest_AxisX + displacement.z * float2(-_Crest_AxisX.y, _Crest_AxisX.x);
_displacement += displacement * weight;
#endif // d_Texture
@@ -249,13 +239,6 @@ void TransferWaves(uint3 id)
_Crest_Target[id] *= 1.0 - saturate(alpha);
#endif
#if !d_Texture
if (_Crest_SeaLevelOnly)
{
_displacement *= saturate(1.0 - abs(level));
}
#endif
// Always write full alpha so textures show up in previews.
_Crest_Target[id] += float4(_displacement, 1.0);
}

View File

@@ -1,8 +1,6 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestExecute
#pragma multi_compile_local d_Sphere d_Cube d_Rectangle

View File

@@ -3,8 +3,6 @@
// Adds clipping from a provided texture. Used by Painted and Texture input modes.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestExecute
#include "HLSLSupport.cginc"

View File

@@ -6,8 +6,6 @@
// afterwards. It is converted to world-space in another shader before writing into
// the LOD data.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestCopy
#pragma kernel CrestFill
@@ -19,7 +17,7 @@
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Globals.hlsl"
Texture2D<float> _CamDepthBuffer;
RWTexture2D<m_Float2> _Crest_Target;
RWTexture2D<float2> _Crest_Target;
#if d_Crest_BackFaceInclusion
Texture2D<float> _Crest_CameraDepthBufferBackfaces;

View File

@@ -5,8 +5,6 @@
// from an ODC, then they are in object-space and are converted to world-space as
// the LOD data stores world-space height.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestExecute
#pragma multi_compile_local __ d_CrestSDF
@@ -24,14 +22,14 @@
#if d_CrestSDF
#undef m_CrestType
#define m_CrestType m_Float2
#define m_CrestType float2
#endif
Texture2D<m_CrestType> _Crest_Texture;
RWTexture2DArray<m_CrestType> _Crest_Target;
CBUFFER_START(CrestInputTexture)
m_CrestType _Crest_Multiplier;
float2 _Crest_Multiplier;
float2 _Crest_TextureSize;
float2 _Crest_TexturePosition;
float2 _Crest_TextureRotation;

View File

@@ -3,8 +3,6 @@
// Adds flow from a provided texture. Used by Painted and Texture input modes.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestExecute
#include "HLSLSupport.cginc"
@@ -17,7 +15,7 @@
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
Texture2D _Crest_Texture;
RWTexture2DArray<m_Float2> _Crest_Target;
RWTexture2DArray<float2> _Crest_Target;
CBUFFER_START(CrestPerMaterial)
int _Crest_Blend;
@@ -64,8 +62,7 @@ void Execute(uint3 id)
}
const float2 target = _Crest_Target[id];
const float2 result = Blend(_Crest_Blend, weight, 1.0, source, target);
_Crest_Target[id] = m_Float2FromFloat2(result);
_Crest_Target[id] = Blend(_Crest_Blend, weight, 1.0, source, target);
}
m_CrestNameSpaceEnd

View File

@@ -3,8 +3,6 @@
// Adds foam from a provided texture. Used by Painted and Texture input modes.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestExecute
#include "HLSLSupport.cginc"

View File

@@ -4,8 +4,6 @@
// An implementation of the Jump Flood algorithm by Rong and Tan
// Source: https://www.comp.nus.edu.sg/~tants/jfa.html
#pragma exclude_renderers glcore gles3
#pragma kernel CrestInitialize
#pragma kernel CrestExecute
#pragma kernel CrestApply
@@ -29,13 +27,13 @@ float _Crest_WaterLevel;
CBUFFER_END
// Holds scene depth for initialization.
Texture2D<m_Float2> _Crest_Source;
RWTexture2D<m_Float2> _Crest_Target;
Texture2D<float2> _Crest_Source;
RWTexture2D<float2> _Crest_Target;
// Setting this to zero means that geometry at exactly the origin won't be handled
// gracefully - but it would only affect a single-pixel in the worst-case and would
// doubtfully be noticable anyway. Use infinity instead.
#define m_CrestUninitializedPosition m_Float2Constructor(m_Crest_PositiveInfinity, m_Crest_PositiveInfinity)
#define m_CrestUninitializedPosition float2(m_Crest_PositiveInfinity, m_Crest_PositiveInfinity)
#if d_Crest_Inverted
#define m_DepthCheck depth > 0.0
@@ -68,7 +66,7 @@ void Initialize(const uint3 id)
depth += lerp(Cascade::MakeLevel(slice0).SampleLevel(position), Cascade::MakeLevel(slice1).SampleLevel(position), alpha);
#endif
_Crest_Target[id.xy] = m_DepthCheck ? m_Float2FromFloat2(position) : m_CrestUninitializedPosition;
_Crest_Target[id.xy] = m_DepthCheck ? position : m_CrestUninitializedPosition;
}
void Execute(const uint3 id)
@@ -113,7 +111,7 @@ void Execute(const uint3 id)
}
}
_Crest_Target[id.xy] = m_Float2FromFloat2(nearest);
_Crest_Target[id.xy] = nearest;
}
void Apply(const uint3 id)
@@ -146,7 +144,7 @@ void Apply(const uint3 id)
result.y = distance;
_Crest_Target[id.xy] = m_Float2FromFloat2(result);
_Crest_Target[id.xy] = result;
}
m_CrestNameSpaceEnd

View File

@@ -3,8 +3,6 @@
// Adds height from a provided texture. Used by Painted and Texture input modes.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestExecute
#pragma multi_compile_local __ d_CatmullRom
@@ -29,7 +27,7 @@ float _Crest_Multiplier;
float2 _Crest_TextureSize;
float2 _Crest_TexturePosition;
float2 _Crest_TextureRotation;
float2 _Crest_TextureResolution;
float2 _Crest_Resolution;
CBUFFER_END
m_CrestNameSpace
@@ -51,7 +49,7 @@ void Execute(uint3 id)
}
#if d_CatmullRom
const float source = Utility::SampleTextureCatmullRom(_Crest_Texture, LODData_linear_clamp_sampler, uv, _Crest_TextureResolution)
const float source = Utility::SampleTextureCatmullRom(_Crest_Texture, LODData_linear_clamp_sampler, uv, _Crest_Resolution)
#else
const float source = _Crest_Texture.SampleLevel(LODData_linear_clamp_sampler, uv, 0.0)
#endif

View File

@@ -1,8 +1,6 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestExecute
#include "HLSLSupport.cginc"

View File

@@ -1,8 +1,6 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestExecute
#include "HLSLSupport.cginc"
@@ -14,7 +12,7 @@
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
RWTexture2DArray<m_Float2> _Crest_Target;
RWTexture2DArray<float2> _Crest_Target;
CBUFFER_START(CrestPerWaterInput)
float3 _Crest_Position;
@@ -118,7 +116,7 @@ void Execute(uint3 id)
// Helps interaction to work at different scales
acceleration /= minimumWavelength;
_Crest_Target[id] = m_Float2Constructor(_Crest_Target[id].x, _Crest_Target[id].y + acceleration * _Crest_SimDeltaTime);
_Crest_Target[id] = float2(_Crest_Target[id].x, _Crest_Target[id].y + acceleration * _Crest_SimDeltaTime);
}
m_CrestNameSpaceEnd

View File

@@ -1,8 +1,6 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestPackLevel
#include "HLSLSupport.cginc"

View File

@@ -1,8 +1,6 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestQueryDisplacement d_CrestDisplacement
#pragma kernel CrestQueryFlow d_CrestFlow
#pragma kernel CrestQueryDepth d_CrestDepth

View File

@@ -3,8 +3,6 @@
// Merged into Query.compute.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestExecute
[numthreads(1, 1, 1)]
void CrestExecute(uint3 id : SV_DispatchThreadID) { }

View File

@@ -3,8 +3,6 @@
// Merged into Query.compute.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestExecute
[numthreads(1, 1, 1)]
void CrestExecute(uint3 id : SV_DispatchThreadID) { }

View File

@@ -1,19 +1,21 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma exclude_renderers glcore gles3
// Compute shader to perform combine of displacements. Reads and writes to texture array which saves
// needing to do ping pong of render targets. Unfortunately reading/writing float4s is not supported
// on pre-DX11.3 hardware (aka typed UAV loads), so this path is not the default, for now..
#pragma kernel CrestShapeCombineAnimatedWaves
#pragma kernel CrestShapeCopyAnimatedWaves
#pragma kernel CrestShapeCombineDynamicWaves d_CombineDynamicWaves
#pragma multi_compile_local _ d_Combine
#pragma multi_compile_local _ d_DynamicWaves
#pragma multi_compile_local _ d_Flow
#if d_CombineDynamicWaves
#define d_DynamicWaves 1
#endif
#pragma kernel ShapeCombine
#pragma kernel ShapeCombine_DISABLE_COMBINE _DISABLE_COMBINE
#pragma kernel ShapeCombine_FLOW_ON _FLOW_ON
#pragma kernel ShapeCombine_FLOW_ON_DISABLE_COMBINE _FLOW_ON _DISABLE_COMBINE
#pragma kernel ShapeCombine_DYNAMIC_WAVE_SIM_ON _DYNAMIC_WAVE_SIM_ON
#pragma kernel ShapeCombine_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE _DYNAMIC_WAVE_SIM_ON _DISABLE_COMBINE
#pragma kernel ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON _FLOW_ON _DYNAMIC_WAVE_SIM_ON
#pragma kernel ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE _FLOW_ON _DYNAMIC_WAVE_SIM_ON _DISABLE_COMBINE
#pragma kernel ShapeCombineDynamicWaves
#pragma kernel ShapeCombineDynamicWaves_DISABLE_COMBINE _DISABLE_COMBINE
#pragma kernel ShapeCombineCopyDynamicWaves
#include "HLSLSupport.cginc"
@@ -28,10 +30,11 @@ float _Crest_DisplaceClamp;
Texture2DArray _Crest_WaveBuffer;
RWTexture2DArray<float4> _Crest_Target;
RWTexture2DArray<float4> _Crest_DynamicWavesTarget;
RWTexture2DArray<float4> _Crest_AnimatedWavesTarget;
m_CrestNameSpace
#if d_Flow
void Flow(const float texel, out float2 offsets, out float2 weights)
{
const float period = max(3.0 * texel, 1.0);
@@ -41,9 +44,7 @@ void Flow(const float texel, out float2 offsets, out float2 weights)
if (weights.x > 1.0) weights.x = 2.0 - weights.x;
weights.y = 1.0 - weights.x;
}
#endif
#if d_Combine
void SampleDisplacementsCompute(
in RWTexture2DArray<float4> i_dispSampler,
in float i_resolution, in float3 i_uv_slice,
@@ -81,11 +82,10 @@ void SampleDisplacementsCompute(
io_worldPos += i_wt * dataLerped.xyz;
}
#endif
void ShapeCombine(uint3 id)
void ShapeCombineBase(uint3 id)
{
const uint slice0 = id.z;
const uint slice0 = _Crest_LodIndex;
const Cascade cascade = Cascade::MakeAnimatedWaves(slice0);
const float3 uv = cascade.IDToUV(id.xy);
@@ -93,25 +93,23 @@ void ShapeCombine(uint3 id)
float3 result = 0.0;
#if !d_CombineDynamicWaves
// Sample in waves for this cascade.
{
#if d_Flow
#if _FLOW_ON
const half2 flow = Cascade::MakeFlow(slice0).SampleFlow(positionWSXZ);
float2 offsets, weights;
Flow(cascade._Texel, offsets, weights);
result += cascade.SampleAnimatedWavesOverflow(_Crest_WaveBuffer, positionWSXZ - offsets.x * flow, 1.0).xyz * weights.x;
result += cascade.SampleAnimatedWavesOverflow(_Crest_WaveBuffer, positionWSXZ - offsets.y * flow, 1.0).xyz * weights.y;
result += cascade.Sample(_Crest_WaveBuffer, positionWSXZ - offsets[0] * flow).xyz * weights[0];
result += cascade.Sample(_Crest_WaveBuffer, positionWSXZ - offsets[1] * flow).xyz * weights[1];
#else
result += _Crest_WaveBuffer[id].xyz;
#endif
result += cascade.Sample(_Crest_WaveBuffer, uv).xyz;
#endif // _FLOW_ON
}
#endif
// Disabled for last LOD.
#if d_Combine
#if !_DISABLE_COMBINE
{
const Cascade cascade = Cascade::MakeAnimatedWaves(slice0 + 1);
// Sample the shape 1 texture at this world position.
@@ -121,37 +119,61 @@ void ShapeCombine(uint3 id)
}
#endif
#if d_DynamicWaves
#if _DYNAMIC_WAVE_SIM_ON
{
// Convert dynamic wave sim to displacements.
result += Cascade::MakeDynamicWaves(slice0)
.SampleDynamicWavesDisplacement(positionWSXZ, _Crest_HorizontalDisplace, _Crest_DisplaceClamp);
}
#endif
#endif // _DYNAMIC_WAVE_SIM_ON
_Crest_Target[id] = float4(result, 0.0);
}
void ShapeCombineAnimatedWaves(uint3 id)
{
id.z = _Crest_LodIndex;
ShapeCombine(id);
}
void ShapeCopyAnimatedWaves(uint3 id)
{
ShapeCombine(id);
_Crest_Target[uint3(id.xy, slice0)] = float4(result, 0.0);
}
void ShapeCombineDynamicWaves(uint3 id)
{
// We are combining from the target which matches the Animated Waves descriptor.
id.z = _Crest_LodIndex;
ShapeCombine(id);
const uint slice0 = _Crest_LodIndex;
const Cascade cascade = Cascade::MakeAnimatedWaves(slice0);
const float3 uv = cascade.IDToUV(id.xy);
const float2 positionWSXZ = cascade.UVToWorld(uv);
float3 result = 0.0;
// Disabled for last LOD.
#if !_DISABLE_COMBINE
{
// We are sampling from the target which matches Animated Waves descriptor.
const Cascade cascade = Cascade::MakeAnimatedWaves(slice0 + 1);
const float3 uv = cascade.WorldToUV(positionWSXZ);
// Waves to combine down from the next lod up the chain.
SampleDisplacementsCompute(_Crest_DynamicWavesTarget, cascade._Resolution, uv, 1.0, result);
}
#endif
{
// We are sampling from Dynamic Waves.
const Cascade cascade = Cascade::MakeDynamicWaves(slice0);
const float3 uv = cascade.WorldToUV(positionWSXZ);
result += cascade.SampleDynamicWavesDisplacement(uv, _Crest_HorizontalDisplace, _Crest_DisplaceClamp);
}
_Crest_DynamicWavesTarget[uint3(id.xy, slice0)] = float4(result, 0.0);
}
void ShapeCombineCopyDynamicWaves(uint3 id)
{
_Crest_AnimatedWavesTarget[id] += _Crest_DynamicWavesTarget[id];
}
m_CrestNameSpaceEnd
m_CrestKernelDefault(ShapeCombineAnimatedWaves)
m_CrestKernelDefault(ShapeCopyAnimatedWaves)
m_CrestKernelDefault(ShapeCombineDynamicWaves)
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void ShapeCombine(uint3 id : SV_DispatchThreadID) { m_Crest::ShapeCombineBase(id); }
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void ShapeCombine_DISABLE_COMBINE(uint3 id : SV_DispatchThreadID) { m_Crest::ShapeCombineBase(id); }
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void ShapeCombine_FLOW_ON(uint3 id : SV_DispatchThreadID) { m_Crest::ShapeCombineBase(id); }
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void ShapeCombine_FLOW_ON_DISABLE_COMBINE(uint3 id : SV_DispatchThreadID) { m_Crest::ShapeCombineBase(id); }
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void ShapeCombine_DYNAMIC_WAVE_SIM_ON(uint3 id : SV_DispatchThreadID) { m_Crest::ShapeCombineBase(id); }
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void ShapeCombine_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE(uint3 id : SV_DispatchThreadID) { m_Crest::ShapeCombineBase(id); }
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON(uint3 id : SV_DispatchThreadID) { m_Crest::ShapeCombineBase(id); }
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE(uint3 id : SV_DispatchThreadID) { m_Crest::ShapeCombineBase(id); }
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void ShapeCombineDynamicWaves(uint3 id : SV_DispatchThreadID) { m_Crest::ShapeCombineDynamicWaves(id); }
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void ShapeCombineDynamicWaves_DISABLE_COMBINE(uint3 id : SV_DispatchThreadID) { m_Crest::ShapeCombineDynamicWaves(id); }
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void ShapeCombineCopyDynamicWaves(uint3 id : SV_DispatchThreadID) { m_Crest::ShapeCombineCopyDynamicWaves(id); }

View File

@@ -1,8 +1,6 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestShorelineColor
#pragma multi_compile_local __ d_Crest_ShorelineColorSource_ShorelineDistance

View File

@@ -3,19 +3,16 @@
// Solves 2D wave equation
#pragma exclude_renderers glcore gles3
#pragma kernel CrestUpdateDynamicWaves
#include "HLSLSupport.cginc"
#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/InputsDriven.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
RWTexture2DArray<m_Float2> _Crest_Target;
RWTexture2DArray<float2> _Crest_Target;
CBUFFER_START(CrestPerMaterial)
float _Crest_Damping;
@@ -48,7 +45,7 @@ void UpdateDynamicWaves(uint3 id)
if (sliceIndexSource < 0.0 || sliceIndexSource >= cascadeSource._Count)
{
// Always initialise with 0 values.
_Crest_Target[id] = 0.0;
_Crest_Target[id] = (float2)0;
return;
}
@@ -75,7 +72,7 @@ void UpdateDynamicWaves(uint3 id)
// Wave reflections off geometry.
if (waterDepth <= 0.0)
{
_Crest_Target[id] = 0.0;
_Crest_Target[id] = float2(0.0, 0.0);
return;
}
@@ -145,7 +142,7 @@ void UpdateDynamicWaves(uint3 id)
vtp = 0.0;
}
_Crest_Target[id] = m_Float2Constructor(ftp, vtp);
_Crest_Target[id] = float2(ftp, vtp);
}
m_CrestNameSpaceEnd

View File

@@ -1,8 +1,6 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestUpdateFoam
#include "HLSLSupport.cginc"
@@ -55,16 +53,9 @@ void UpdateFoam(uint3 id)
// accumulation of foam and causes overshoots when _Crest_WaveFoamStrength is less than 1.0.
float simDeltaTime = _Crest_NeedsPrewarming ? max(_Crest_SimDeltaTime, min(1.0, _Crest_WaveFoamStrength - 1.0) / _Crest_FoamFadeRate) : _Crest_SimDeltaTime;
// Limit wave contributions at low water scales only where filtering is needed.
uint filteredSlice = slice0;
if (g_Crest_WaterScale <= 8)
{
filteredSlice = max(_Crest_MinimumWavesSlice, filteredSlice);
}
// The determinant of the displacement Jacobian is a good measure for turbulence.
float det;
const half3 displacement = Cascade::MakeAnimatedWaves(filteredSlice).SampleDisplacement(worldPosXZ, det);
const half3 displacement = Cascade::MakeAnimatedWaves(max(_Crest_MinimumWavesSlice, slice0)).SampleDisplacement(worldPosXZ, det);
foam += 5.0 * simDeltaTime * _Crest_WaveFoamStrength * saturate( _Crest_WaveFoamCoverage - det );
// Prewarm shoreline foam. 1.0 / _Crest_FoamFadeRate perfectly matches a paused water in edit mode which is fine for

View File

@@ -3,8 +3,6 @@
// Soft shadow term is red, hard shadow term is green.
#pragma exclude_renderers glcore gles3
#pragma kernel CrestUpdateShadowsBRP _BRP
#pragma kernel CrestUpdateShadowsHRP _HRP
#pragma kernel CrestUpdateShadowsURP _URP
@@ -35,7 +33,7 @@ bool _Crest_SampleColorMap;
float3 _Crest_Absorption;
float3 _Crest_Scattering;
RWTexture2DArray<m_Float2> _Crest_Target;
RWTexture2DArray<float2> _Crest_Target;
m_CrestNameSpace
@@ -148,7 +146,7 @@ void UpdateShadows(const uint3 id)
shadow = lerp(shadow, shadowThisFrame, _Crest_JitterDiameters_CurrentFrameWeights.zw * _Crest_SimDeltaTime * 60.0);
}
_Crest_Target[id] = m_Float2FromFloat2(shadow);
_Crest_Target[id] = shadow;
}
m_CrestNameSpaceEnd

View File

@@ -1,4 +1,176 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// Replaced with UpdateShadow.compute.
// Soft shadow term is red, hard shadow term is green. In HDRP, hard shadows are not computed and y channel will be 0.
#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/InputsDriven.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
// Noise functions used for jitter.
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Noise/Noise.hlsl"
CBUFFER_START(CrestPerMaterial)
// Settings._jitterDiameterSoft, Settings._jitterDiameterHard, Settings._currentFrameWeightSoft, Settings._currentFrameWeightHard
float4 _Crest_JitterDiameters_CurrentFrameWeights;
float _Crest_SimDeltaTime;
bool _Crest_ClearShadows;
float3 _Crest_CenterPos;
float3 _Crest_Scale;
float4x4 _Crest_MainCameraProjectionMatrix;
bool _Crest_SampleColorMap;
float3 _Crest_Absorption;
float3 _Crest_Scattering;
CBUFFER_END
m_CrestNameSpace
struct Attributes
{
uint id : SV_VertexID;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float3 positionWS : 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);
float2 uv = GetFullScreenTriangleTexCoord(input.id);
// World position from UV.
output.positionWS.xyz = float3(uv.x - 0.5, 0.0, uv.y - 0.5) * _Crest_Scale * 4.0 + _Crest_CenterPos;
output.positionWS.y = g_Crest_WaterCenter.y;
return output;
}
half SampleShadows(const float4 i_positionWS);
half ComputeShadowFade(const float4 i_positionWS);
// Compiler shows warning when using intermediate returns, disable this.
#pragma warning(push)
#pragma warning(disable: 4000)
half ComputeShadow(const float4 i_positionWS, const float i_jitterDiameter, const half i_terrainHeight)
{
float4 positionWS = i_positionWS;
if (i_jitterDiameter > 0.0)
{
// Add jitter.
positionWS.xz += i_jitterDiameter * (hash33(uint3(abs(positionWS.xz * 10.0), _Time.y * 120.0)) - 0.5).xy;
// Shadow Bleeding.
// If we are not within a terrain, then check for shadow bleeding.
if (i_positionWS.y > i_terrainHeight)
{
// WorldToSafeUV
half terrainHeight = Cascade::MakeDepth(_Crest_LodIndex).SampleSceneHeight(positionWS.xz);
// If our current position is below the jittered terrain height, then we have landed within a terrain and
// we do not want to sample those shadows.
if (i_positionWS.y < terrainHeight)
{
// Return no shadows.
return 1.0;
}
}
}
return SampleShadows(positionWS);
}
#pragma warning(pop)
half2 Fragment(Varyings input)
{
float4 positionWS = float4(input.positionWS.xyz, 1.0);
// Shadow from last frame. Manually implement black border.
const float sliceIndexSource = clamp((int)_Crest_LodIndex + g_Crest_LodChange, 0.0, g_Crest_LodCount - 1.0);
half2 shadow = Cascade::MakeShadowSource(sliceIndexSource).SampleShadowOverflow(positionWS.xz, 1.0);
// Add displacement so shorelines do not receive shadows incorrectly.
positionWS.xyz += Cascade::MakeAnimatedWaves(_Crest_LodIndex).SampleDisplacement(positionWS.xz);
// This was calculated in vertex but we have to sample sea level offset in fragment.
float4 mainCameraCoordinates = mul(_Crest_MainCameraProjectionMatrix, positionWS);
// Check if the current sample is visible in the main camera (and therefore the shadow map can be sampled). This is
// required as the shadow buffer is world aligned and surrounds viewer.
float3 projected = mainCameraCoordinates.xyz / mainCameraCoordinates.w;
if (projected.z < 1.0 && projected.z > 0.0 && abs(projected.x) < 1.0 && abs(projected.y) < 1.0)
{
half2 shadowThisFrame = 1.0;
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
positionWS.xyz -= _WorldSpaceCameraPos.xyz;
#endif
half terrainHeight = Cascade::MakeDepth(_Crest_LodIndex).SampleSceneHeight(positionWS.xz);
half softJitter = _Crest_JitterDiameters_CurrentFrameWeights[CREST_SHADOW_INDEX_SOFT];
if (_Crest_SampleColorMap)
{
half3 absorption = _Crest_Absorption;
half3 scattering = _Crest_Scattering;
if (g_Crest_SampleAbsorptionSimulation)
{
absorption = Cascade::MakeAbsorption(_Crest_LodIndex).SampleAbsorption(positionWS.xz);
}
if (g_Crest_SampleScatteringSimulation)
{
scattering = Cascade::MakeScattering(_Crest_LodIndex).SampleScattering(positionWS.xz);
}
half3 extinction = absorption + scattering;
half factor = saturate(min(min(extinction.x, extinction.y), extinction.z) * g_Crest_DynamicSoftShadowsFactor);
softJitter = (1.0 - factor) * k_Crest_MaximumShadowJitter;
}
// Add soft shadowing data.
shadowThisFrame[CREST_SHADOW_INDEX_SOFT] = ComputeShadow
(
positionWS,
softJitter,
terrainHeight
);
#ifdef CREST_SAMPLE_SHADOW_HARD
// Add hard shadowing data.
shadowThisFrame[CREST_SHADOW_INDEX_HARD] = ComputeShadow
(
positionWS,
_Crest_JitterDiameters_CurrentFrameWeights[CREST_SHADOW_INDEX_HARD],
terrainHeight
);
#endif
shadowThisFrame = (half2)1.0 - saturate(shadowThisFrame + ComputeShadowFade(positionWS));
shadow = lerp(shadow, shadowThisFrame, _Crest_JitterDiameters_CurrentFrameWeights.zw * _Crest_SimDeltaTime * 60.0);
}
return shadow;
}
m_CrestNameSpaceEnd
m_CrestVertex
m_CrestFragment(half2)