移除水
This commit is contained in:
@@ -1,54 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#pragma kernel CrestExecute
|
||||
|
||||
#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/Helpers.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
|
||||
|
||||
Texture2D _Crest_Texture;
|
||||
RWTexture2DArray<float3> _Crest_Target;
|
||||
|
||||
CBUFFER_START(CrestPerMaterial)
|
||||
int _Crest_Blend;
|
||||
float _Crest_Weight;
|
||||
float2 _Crest_TextureSize;
|
||||
float2 _Crest_TexturePosition;
|
||||
float2 _Crest_TextureRotation;
|
||||
float _Crest_FeatherWidth;
|
||||
CBUFFER_END
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
void Execute(uint3 id)
|
||||
{
|
||||
const Cascade cascade = Cascade::MakeAbsorption(id.z);
|
||||
const float2 uv = DataIDToInputUV(id.xy, cascade, _Crest_TexturePosition, _Crest_TextureRotation, _Crest_TextureSize);
|
||||
|
||||
half weight = _Crest_Weight;
|
||||
|
||||
// Feather boundaries.
|
||||
weight *= FeatherWeightFromUV(uv, _Crest_FeatherWidth);
|
||||
|
||||
// Check we are within bounds.
|
||||
if (weight <= 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const half4 source = _Crest_Texture.SampleLevel(LODData_linear_clamp_sampler, uv, 0);
|
||||
const half3 target = _Crest_Target[id];
|
||||
weight *= source.a;
|
||||
|
||||
_Crest_Target[id] = Blend(_Crest_Blend, weight, 1.0, source.xyz, target);
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestInputKernelDefault(Execute)
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82d4c3f5aac084c2bad20d0a31f1168a
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,248 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#pragma kernel CrestTransferWaves
|
||||
|
||||
#pragma multi_compile_local __ d_Texture d_TextureBlend
|
||||
|
||||
#if defined(d_TextureBlend)
|
||||
#define d_Texture 1
|
||||
#endif
|
||||
|
||||
#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/Helpers.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
|
||||
|
||||
Texture2D _Crest_Texture;
|
||||
Texture2DArray _Crest_WaveBuffer;
|
||||
RWTexture2DArray<float4> _Crest_Target;
|
||||
|
||||
CBUFFER_START(CrestPerMaterial)
|
||||
float4 _Crest_WaveBufferParameters[MAX_LOD_COUNT];
|
||||
float2 _Crest_AxisX;
|
||||
float _Crest_Weight;
|
||||
float _Crest_FeatherWidth;
|
||||
float _Crest_AttenuationInShallows;
|
||||
float _Crest_RespectShallowWaterAttenuation;
|
||||
float _Crest_MaximumAttenuationDepth;
|
||||
float _Crest_WaveResolutionMultiplier;
|
||||
float _Crest_TransitionalWavelengthThreshold;
|
||||
|
||||
// Texture
|
||||
#if d_Texture
|
||||
float2 _Crest_TextureSize;
|
||||
float2 _Crest_TexturePosition;
|
||||
float2 _Crest_TextureRotation;
|
||||
bool _Crest_NegativeValues;
|
||||
int _Crest_Blend;
|
||||
#endif
|
||||
CBUFFER_END
|
||||
|
||||
#if d_Texture
|
||||
#define m_None 0
|
||||
#define m_FromZero 4
|
||||
#define m_FromZeroNormalized 5
|
||||
#endif // d_Texture
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
void TransferWaves(uint3 id)
|
||||
{
|
||||
const uint slice0 = id.z;
|
||||
|
||||
const float4 parameters = _Crest_WaveBufferParameters[slice0];
|
||||
const uint first = parameters.x;
|
||||
const uint last = parameters.y;
|
||||
const half transition = parameters.w;
|
||||
|
||||
#if !d_TextureBlend
|
||||
// Additive only. All wavelengths filtered out for this LOD so nothing to do.
|
||||
if (parameters.x < 0 || parameters.y < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
const Cascade cascade = Cascade::MakeAnimatedWaves(slice0);
|
||||
const float2 positionWS = cascade.IDToWorld(id.xy);
|
||||
|
||||
half _weight = _Crest_Weight;
|
||||
half alpha = 0.0;
|
||||
|
||||
#if d_Texture
|
||||
float2 uvPainted = (positionWS - _Crest_TexturePosition) / _Crest_TextureSize;
|
||||
// Clockwise transform rotation.
|
||||
uvPainted = uvPainted.x * float2(_Crest_TextureRotation.y, -_Crest_TextureRotation.x) + uvPainted.y * _Crest_TextureRotation;
|
||||
uvPainted += 0.5;
|
||||
|
||||
// Feather boundaries.
|
||||
_weight *= FeatherWeightFromUV(uvPainted, _Crest_FeatherWidth);
|
||||
|
||||
// Check we are within bounds.
|
||||
if (_weight <= 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
alpha = _weight;
|
||||
|
||||
// Initialize or "use of potentially uninitialized variable" due to early return.
|
||||
float2 axis; float axisLength = 0.0; float t = 0.0;
|
||||
float2 axisX0 = 0.0; float2 axisX1 = 0.0; float2 axisZ0 = 0.0; float2 axisZ1 = 0.0;
|
||||
{
|
||||
axis = _Crest_Texture.SampleLevel(LODData_linear_clamp_sampler, uvPainted, 0).xy;
|
||||
|
||||
if (!_Crest_NegativeValues)
|
||||
{
|
||||
// -1.0 to 1.0
|
||||
axis = axis * 2.0 - 1.0;
|
||||
}
|
||||
|
||||
float axisLength2 = dot(axis, axis);
|
||||
|
||||
// Zero data so exit early and apply blending if needed.
|
||||
if (!(axisLength2 > 0.00001))
|
||||
{
|
||||
#if d_TextureBlend
|
||||
if (_Crest_Blend > m_None)
|
||||
{
|
||||
// If zero affects blend weight, then reduce alpha by axis length so that it
|
||||
// accounts for zero data.
|
||||
alpha = 0.0;
|
||||
}
|
||||
|
||||
_Crest_Target[id] *= 1.0 - alpha;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
axisLength = sqrt(axisLength2);
|
||||
|
||||
// Alpha blending based on data.
|
||||
if (_Crest_Blend == m_FromZeroNormalized)
|
||||
{
|
||||
// Normalize so even small amounts fully removes existing waves.
|
||||
alpha *= length(normalize(axis));
|
||||
}
|
||||
else if (_Crest_Blend == m_FromZero)
|
||||
{
|
||||
alpha *= axisLength;
|
||||
}
|
||||
|
||||
// Rotate axis with transform rotation to keep axis in local space.
|
||||
axis = axis.x * _Crest_TextureRotation.yx + axis.y * float2(-_Crest_TextureRotation.x, _Crest_TextureRotation.y);
|
||||
|
||||
// Add wind (counterclockwise).
|
||||
axis = axis.x * _Crest_AxisX + axis.y * float2(-_Crest_AxisX.y, _Crest_AxisX.x);
|
||||
|
||||
// Quantize wave direction.
|
||||
const float axisHeading = atan2(axis.y, axis.x) + 2.0 * 3.141592654;
|
||||
const float dTheta = 0.5 * 0.314159265;
|
||||
const float rem = fmod(axisHeading, dTheta);
|
||||
const float angle0 = axisHeading - rem;
|
||||
const float angle1 = angle0 + dTheta;
|
||||
t = rem / dTheta;
|
||||
|
||||
sincos(angle0, axisX0.y, axisX0.x);
|
||||
sincos(angle1, axisX1.y, axisX1.x);
|
||||
axisZ0.x = -axisX0.y; axisZ0.y = axisX0.x;
|
||||
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 depth = Cascade::MakeDepth(slice0).SampleSignedDepthFromSeaLevel(positionWS) +
|
||||
Cascade::MakeLevel(slice0).SampleLevel(positionWS);
|
||||
|
||||
half3 _displacement = 0.0;
|
||||
|
||||
// Loop through wave buffer slices.
|
||||
for (uint i = first; i <= last; i++)
|
||||
{
|
||||
const uint waveBufferIndex = i;
|
||||
const float waveBufferSize = 0.5f * (1 << waveBufferIndex);
|
||||
|
||||
half weight = _weight;
|
||||
|
||||
uint WAVE_SAMPLE_FACTOR = 8;
|
||||
half minimumWL = waveBufferSize / WAVE_SAMPLE_FACTOR / _Crest_WaveResolutionMultiplier;
|
||||
half averageWL = minimumWL * 1.5f * _Crest_WaveResolutionMultiplier;
|
||||
|
||||
// If approaching end of lod chain, start smoothly transitioning any large
|
||||
// wavelengths across last two LODs.
|
||||
if (minimumWL >= _Crest_TransitionalWavelengthThreshold)
|
||||
{
|
||||
// The transition weight must not be applied to the alpha otherwise popping.
|
||||
weight *= transition;
|
||||
}
|
||||
|
||||
// Attenuation.
|
||||
float attenuation;
|
||||
{
|
||||
// Attenuate waves based on water depth. If depth is greater than half the
|
||||
// wavelength, water is considered deep and wave is unaffected. If depth is less
|
||||
// than this, wave velocity decreases. Waves will then bunch up and grow in
|
||||
// amplitude and eventually break. Deep water model is approximated by simply
|
||||
// ramping down waves in non-deep water with a linear multiplier.
|
||||
// http://hyperphysics.phy-astr.gsu.edu/hbase/Waves/watwav2.html
|
||||
// http://hyperphysics.phy-astr.gsu.edu/hbase/watwav.html#c1
|
||||
half weight = saturate(2.0 * depth / averageWL);
|
||||
if (_Crest_MaximumAttenuationDepth < k_Crest_MaximumWaveAttenuationDepth)
|
||||
{
|
||||
weight = lerp(weight, 1.0, saturate(depth / _Crest_MaximumAttenuationDepth));
|
||||
}
|
||||
|
||||
|
||||
const float attenuationAmount = _Crest_AttenuationInShallows * _Crest_RespectShallowWaterAttenuation;
|
||||
attenuation = attenuationAmount * weight + (1.0 - attenuationAmount);
|
||||
}
|
||||
|
||||
// NOTE: Could not get attenuation applied to alpha to work. Incurred popping.
|
||||
weight *= attenuation;
|
||||
|
||||
// Sample Wave Buffers.
|
||||
if (weight > 0.0)
|
||||
{
|
||||
#if d_Texture
|
||||
// Interpolate waves.
|
||||
float2 positionScaledWS = positionWS / waveBufferSize;
|
||||
|
||||
const float2 uv0 = float2(dot(positionScaledWS, axisX0), dot(positionScaledWS, axisZ0));
|
||||
const float2 uv1 = float2(dot(positionScaledWS, axisX1), dot(positionScaledWS, axisZ1));
|
||||
|
||||
// Sample displacement, rotate into frame.
|
||||
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);
|
||||
displacement.y *= axisLength;
|
||||
_displacement += displacement * weight;
|
||||
|
||||
#else // !d_Texture
|
||||
// Sample displacement, rotate into frame defined by global wind direction.
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
#if d_TextureBlend
|
||||
// Global waves are always additive.
|
||||
_Crest_Target[id] *= 1.0 - saturate(alpha);
|
||||
#endif
|
||||
|
||||
// Always write full alpha so textures show up in previews.
|
||||
_Crest_Target[id] += float4(_displacement, 1.0);
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestInputKernelDefault(TransferWaves)
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a487d04e47a14907809657d5ccf1917
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,92 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// Renders convex hull to the clip surface texture.
|
||||
|
||||
Shader "Hidden/Crest/Inputs/Clip/Convex Hull"
|
||||
{
|
||||
CGINCLUDE
|
||||
#pragma vertex Vertex
|
||||
#pragma fragment Fragment
|
||||
|
||||
// For SV_IsFrontFace.
|
||||
#pragma target 3.0
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#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"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Surface/Geometry.hlsl"
|
||||
|
||||
CBUFFER_START(CrestPerWaterInput)
|
||||
bool _Crest_Inverted;
|
||||
CBUFFER_END
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
struct Attributes
|
||||
{
|
||||
float3 positionOS : POSITION;
|
||||
};
|
||||
|
||||
struct Varyings
|
||||
{
|
||||
float4 positionCS : SV_POSITION;
|
||||
float3 positionWS : TEXCOORD0;
|
||||
};
|
||||
|
||||
Varyings Vertex(Attributes input)
|
||||
{
|
||||
Varyings o;
|
||||
o.positionCS = UnityObjectToClipPos(input.positionOS);
|
||||
o.positionWS = mul(unity_ObjectToWorld, float4(input.positionOS, 1.0));
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 Fragment(Varyings input, const bool isFrontFace)
|
||||
{
|
||||
float3 surfacePositionWS = Cascade::MakeAnimatedWaves(_Crest_LodIndex)
|
||||
.SampleDisplacementFromUndisplaced(input.positionWS.xz);
|
||||
|
||||
// Move to sea level.
|
||||
surfacePositionWS.y += g_Crest_WaterCenter.y;
|
||||
|
||||
// Clip if above water.
|
||||
if (input.positionWS.y > surfacePositionWS.y)
|
||||
{
|
||||
clip(-1.0);
|
||||
}
|
||||
|
||||
// To add clipping, back face must write one and front face must write zero.
|
||||
return float4(isFrontFace == _Crest_Inverted ? 1.0 : 0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestVertex
|
||||
m_CrestFragmentWithFrontFace(float4)
|
||||
|
||||
ENDCG
|
||||
|
||||
SubShader
|
||||
{
|
||||
ZWrite Off
|
||||
ColorMask R
|
||||
|
||||
Pass
|
||||
{
|
||||
Cull Front
|
||||
// Here so CGINCLUDE works.
|
||||
CGPROGRAM
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
Cull Back
|
||||
// Here so CGINCLUDE works.
|
||||
CGPROGRAM
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f5d1e029c7564da8855bf97e3b9247a
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,97 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#pragma kernel CrestExecute
|
||||
|
||||
#pragma multi_compile_local d_Sphere d_Cube d_Rectangle
|
||||
#pragma multi_compile_local __ d_Inverted
|
||||
|
||||
#include "HLSLSupport.cginc"
|
||||
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Constants.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Globals.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
|
||||
|
||||
RWTexture2DArray<float1> _Crest_Target;
|
||||
|
||||
CBUFFER_START(CrestPerMaterial)
|
||||
float3 _Crest_Position;
|
||||
float _Crest_Diameter;
|
||||
float4x4 _Crest_Matrix;
|
||||
CBUFFER_END
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
// Also covers elipsoids etc.
|
||||
float SphereSDF(float3 position)
|
||||
{
|
||||
// Distance from center.
|
||||
return length(position);
|
||||
}
|
||||
|
||||
// Also covers rectangular prisms etc.
|
||||
float CubeSDF(float3 position)
|
||||
{
|
||||
// Restrict to one quadrant of a box.
|
||||
position = abs(position);
|
||||
// Get furthest distance from center.
|
||||
return max(position.x, max(position.y, position.z));
|
||||
}
|
||||
|
||||
float RectangleSDF(float2 position)
|
||||
{
|
||||
// Restrict to one quadrant of a box.
|
||||
position = abs(position);
|
||||
// Get furthest distance from center.
|
||||
return max(position.x, position.y);
|
||||
}
|
||||
|
||||
void Execute(uint3 id)
|
||||
{
|
||||
const Cascade cascade = Cascade::MakeClip(id.z);
|
||||
const float2 positionXZ = cascade.IDToWorld(id.xy);
|
||||
|
||||
// TODO: Optimize with something better than spherical culling.
|
||||
// Spherical culling. Check diameter for buffered area.
|
||||
if (length(positionXZ - _Crest_Position.xz) > _Crest_Diameter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float3 position = 0.0;
|
||||
position.xz = positionXZ;
|
||||
|
||||
#if !d_Rectangle
|
||||
// Only need height as clip surface is sampled at the displaced position.
|
||||
const float3 surface = Cascade::MakeAnimatedWaves(id.z).SampleDisplacementFromUndisplaced(positionXZ);
|
||||
position.y = g_Crest_WaterCenter.y + surface.y;
|
||||
#endif
|
||||
|
||||
// SDF operate in local space.
|
||||
position = mul(_Crest_Matrix, float4(position, 1.0)).xyz;
|
||||
|
||||
float sdf = 0;
|
||||
|
||||
#if d_Sphere
|
||||
sdf = SphereSDF(position);
|
||||
#endif
|
||||
|
||||
#if d_Cube
|
||||
sdf = CubeSDF(position);
|
||||
#endif
|
||||
|
||||
#if d_Rectangle
|
||||
sdf = RectangleSDF(position.xz);
|
||||
#endif
|
||||
|
||||
#if d_Inverted
|
||||
_Crest_Target[id.xyz] = min(_Crest_Target[id.xyz], sdf);
|
||||
#else
|
||||
sdf = 1.0 - sdf;
|
||||
_Crest_Target[id.xyz] = max(_Crest_Target[id.xyz], sdf);
|
||||
#endif
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestInputKernelDefault(Execute)
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad943abdbda794e98b8decce3329fcd8
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,47 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// Adds clipping from a provided texture. Used by Painted and Texture input modes.
|
||||
|
||||
#pragma kernel CrestExecute
|
||||
|
||||
#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/Helpers.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
|
||||
|
||||
Texture2D _Crest_Texture;
|
||||
RWTexture2DArray<float> _Crest_Target;
|
||||
|
||||
CBUFFER_START(CrestPerMaterial)
|
||||
float2 _Crest_TextureSize;
|
||||
float2 _Crest_TexturePosition;
|
||||
float2 _Crest_TextureRotation;
|
||||
CBUFFER_END
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
void Execute(uint3 id)
|
||||
{
|
||||
const Cascade cascade = Cascade::MakeClip(id.z);
|
||||
const float2 uv = DataIDToInputUV(id.xy, cascade, _Crest_TexturePosition, _Crest_TextureRotation, _Crest_TextureSize);
|
||||
|
||||
// Check we are within bounds.
|
||||
if (!WithinUV(uv))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const float result = _Crest_Texture.SampleLevel(LODData_linear_clamp_sampler, uv, 0).x;
|
||||
|
||||
// Painted clip defines a minimum value of the clip.
|
||||
_Crest_Target[id] = max(_Crest_Target[id], result);
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestInputKernelDefault(Execute)
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb559b0e067b5464792b8e434189347c
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,4 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
Shader "Hidden/Crest" { }
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cdf2728920d024e9fb0e708e1dc364bb
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,128 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// Copies the depth buffer into the cache as object-space height. Object-space is
|
||||
// used instead of world-space to allow relative movement of baked depth caches
|
||||
// afterwards. It is converted to world-space in another shader before writing into
|
||||
// the LOD data.
|
||||
|
||||
#pragma kernel CrestCopy
|
||||
#pragma kernel CrestFill
|
||||
|
||||
#pragma multi_compile_local __ d_Crest_BackFaceInclusion
|
||||
|
||||
#include "HLSLSupport.cginc"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Constants.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Globals.hlsl"
|
||||
|
||||
Texture2D<float> _CamDepthBuffer;
|
||||
RWTexture2D<float2> _Crest_Target;
|
||||
|
||||
#if d_Crest_BackFaceInclusion
|
||||
Texture2D<float> _Crest_CameraDepthBufferBackfaces;
|
||||
#endif
|
||||
|
||||
CBUFFER_START(CrestPerMaterial)
|
||||
float4 _HeightNearHeightFar;
|
||||
float4 _CustomZBufferParams;
|
||||
float _HeightOffset;
|
||||
float _Crest_PreviousPlane;
|
||||
CBUFFER_END
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
float CustomLinear01Depth(const float z)
|
||||
{
|
||||
return (1.0 - z * _CustomZBufferParams.x) / _CustomZBufferParams.y;
|
||||
}
|
||||
|
||||
void Copy(const uint3 id)
|
||||
{
|
||||
const float deviceDepth = _CamDepthBuffer[id.xy].x;
|
||||
|
||||
// If geometry has been clipped by far plane, set the maximum depth.
|
||||
if (deviceDepth <= 0.0)
|
||||
{
|
||||
_Crest_Target[id.xy] = -CREST_WATER_DEPTH_BASELINE;
|
||||
return;
|
||||
}
|
||||
|
||||
const float linear01Z = CustomLinear01Depth(deviceDepth);
|
||||
|
||||
const float altitude =
|
||||
#if UNITY_REVERSED_Z
|
||||
lerp(_HeightNearHeightFar.y, _HeightNearHeightFar.x, linear01Z);
|
||||
#else
|
||||
lerp(_HeightNearHeightFar.x, _HeightNearHeightFar.y, linear01Z);
|
||||
#endif
|
||||
|
||||
_Crest_Target[id.xy] = altitude - _HeightOffset;
|
||||
}
|
||||
|
||||
void Fill(const uint3 id)
|
||||
{
|
||||
const float deviceDepth = _CamDepthBuffer[id.xy].x;
|
||||
|
||||
#if d_Crest_BackFaceInclusion
|
||||
const float deviceBackFaceDepth = _Crest_CameraDepthBufferBackfaces[id.xy].x;
|
||||
#endif
|
||||
|
||||
// If geometry has been clipped by far plane, set the maximum depth.
|
||||
if (deviceDepth <= 0.0)
|
||||
{
|
||||
#if d_Crest_BackFaceInclusion
|
||||
if (deviceBackFaceDepth <= 0.0)
|
||||
#endif
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If not a hole, do not proceed.
|
||||
// We must be limiteed by precision on trying to represent depth baseline
|
||||
if (_Crest_Target[id.xy].x > -CREST_WATER_DEPTH_BASELINE)
|
||||
{
|
||||
#if d_Crest_BackFaceInclusion
|
||||
if (deviceBackFaceDepth <= 0.0)
|
||||
#endif
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const float linear01Z = CustomLinear01Depth(deviceDepth);
|
||||
|
||||
const float altitude =
|
||||
#if UNITY_REVERSED_Z
|
||||
lerp(_HeightNearHeightFar.y, _HeightNearHeightFar.x, linear01Z);
|
||||
#else
|
||||
lerp(_HeightNearHeightFar.x, _HeightNearHeightFar.y, linear01Z);
|
||||
#endif
|
||||
|
||||
|
||||
#if d_Crest_BackFaceInclusion
|
||||
{
|
||||
const float linear01Z = CustomLinear01Depth(deviceBackFaceDepth);
|
||||
const float altitude =
|
||||
#if UNITY_REVERSED_Z
|
||||
lerp(_HeightNearHeightFar.y, _HeightNearHeightFar.x, linear01Z);
|
||||
#else
|
||||
lerp(_HeightNearHeightFar.x, _HeightNearHeightFar.y, linear01Z);
|
||||
#endif
|
||||
|
||||
// Check backfaces.
|
||||
if (altitude > (_Crest_PreviousPlane + 0.00001))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
_Crest_Target[id.xy] = altitude - _HeightOffset;
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestKernelDefault(Copy)
|
||||
m_CrestKernelDefault(Fill)
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6bb3e13f5a77e489584dd6fe9dd28a4f
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,69 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// Draw cached world-space heights into current frame data. If heights are coming
|
||||
// from an ODC, then they are in object-space and are converted to world-space as
|
||||
// the LOD data stores world-space height.
|
||||
|
||||
#pragma kernel CrestExecute
|
||||
|
||||
#pragma multi_compile_local __ d_CrestSDF
|
||||
|
||||
#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/Helpers.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
|
||||
|
||||
#define m_CrestType float
|
||||
|
||||
#if d_CrestSDF
|
||||
#undef m_CrestType
|
||||
#define m_CrestType float2
|
||||
#endif
|
||||
|
||||
Texture2D<m_CrestType> _Crest_Texture;
|
||||
RWTexture2DArray<m_CrestType> _Crest_Target;
|
||||
|
||||
CBUFFER_START(CrestInputTexture)
|
||||
float2 _Crest_TextureSize;
|
||||
float2 _Crest_TexturePosition;
|
||||
float2 _Crest_TextureRotation;
|
||||
float _Crest_HeightOffset;
|
||||
bool _Crest_SDF;
|
||||
CBUFFER_END
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
void Execute(uint3 id)
|
||||
{
|
||||
const Cascade cascade = Cascade::MakeDepth(id.z);
|
||||
const float2 uv = DataIDToInputUV(id.xy, cascade, _Crest_TexturePosition, _Crest_TextureRotation, _Crest_TextureSize);
|
||||
|
||||
// Check we are within bounds.
|
||||
if (!WithinUV(uv))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_CrestType current = _Crest_Target[id];
|
||||
m_CrestType result = _Crest_Texture.SampleLevel(LODData_linear_clamp_sampler, uv, 0);
|
||||
result.x += _Crest_HeightOffset;
|
||||
|
||||
// Take highest terrain height.
|
||||
result.x = max(current.x, result.x);
|
||||
|
||||
#if d_CrestSDF
|
||||
// Take shortest distance.
|
||||
result.y = _Crest_SDF ? min(current.y, result.y) : current.y;
|
||||
#endif
|
||||
|
||||
_Crest_Target[id] = result;
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestInputKernelDefault(Execute)
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 025c29236eb8341f0a2078d93379be6a
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,67 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// Adds flow from a provided texture. Used by Painted and Texture input modes.
|
||||
|
||||
#pragma kernel CrestExecute
|
||||
|
||||
#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/Helpers.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
|
||||
|
||||
Texture2D _Crest_Texture;
|
||||
RWTexture2DArray<float2> _Crest_Target;
|
||||
|
||||
CBUFFER_START(CrestPerMaterial)
|
||||
int _Crest_Blend;
|
||||
float _Crest_Weight;
|
||||
float2 _Crest_TextureSize;
|
||||
float2 _Crest_TexturePosition;
|
||||
float2 _Crest_TextureRotation;
|
||||
float _Crest_FeatherWidth;
|
||||
bool _Crest_NegativeValues;
|
||||
CBUFFER_END
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
void Execute(uint3 id)
|
||||
{
|
||||
const Cascade cascade = Cascade::MakeFlow(id.z);
|
||||
const float2 uv = DataIDToInputUV(id.xy, cascade, _Crest_TexturePosition, _Crest_TextureRotation, _Crest_TextureSize);
|
||||
|
||||
half weight = _Crest_Weight;
|
||||
|
||||
// Feather boundaries.
|
||||
weight *= FeatherWeightFromUV(uv, _Crest_FeatherWidth);
|
||||
|
||||
// Check we are within bounds.
|
||||
if (weight <= 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float2 source = _Crest_Texture.SampleLevel(LODData_linear_clamp_sampler, uv, 0).xy;
|
||||
|
||||
if (!_Crest_NegativeValues)
|
||||
{
|
||||
// From 0..1 to -1..1.
|
||||
source = source * 2.0 - 1.0;
|
||||
}
|
||||
|
||||
if (_Crest_Blend == m_CrestBlendAlpha)
|
||||
{
|
||||
weight *= saturate(length(source));
|
||||
}
|
||||
|
||||
const float2 target = _Crest_Target[id];
|
||||
_Crest_Target[id] = Blend(_Crest_Blend, weight, 1.0, source, target);
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestInputKernelDefault(Execute)
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67ee915fe51504dd894c5cbf6f1a7868
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,56 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// Adds foam from a provided texture. Used by Painted and Texture input modes.
|
||||
|
||||
#pragma kernel CrestExecute
|
||||
|
||||
#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/Helpers.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
|
||||
|
||||
Texture2D _Crest_Texture;
|
||||
RWTexture2DArray<float> _Crest_Target;
|
||||
|
||||
CBUFFER_START(CrestPerMaterial)
|
||||
int _Crest_Blend;
|
||||
float _Crest_Weight;
|
||||
float2 _Crest_TextureSize;
|
||||
float2 _Crest_TexturePosition;
|
||||
float2 _Crest_TextureRotation;
|
||||
float _Crest_FeatherWidth;
|
||||
float _Crest_SimDeltaTime;
|
||||
CBUFFER_END
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
void Execute(uint3 id)
|
||||
{
|
||||
const Cascade cascade = Cascade::MakeFoam(id.z);
|
||||
const float2 uv = DataIDToInputUV(id.xy, cascade, _Crest_TexturePosition, _Crest_TextureRotation, _Crest_TextureSize);
|
||||
|
||||
half weight = _Crest_Weight;
|
||||
|
||||
// Boundary check with feathering.
|
||||
weight *= FeatherWeightFromUV(uv, _Crest_FeatherWidth);
|
||||
|
||||
// Check we are within bounds.
|
||||
if (weight <= 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const float source = _Crest_Texture.SampleLevel(LODData_linear_clamp_sampler, uv, 0).x;
|
||||
const float target = _Crest_Target[id];
|
||||
|
||||
_Crest_Target[id] = Blend(_Crest_Blend, weight, _Crest_SimDeltaTime, source, target);
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestInputKernelDefault(Execute)
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69307e5986e134adc90ee257e7dba1ea
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,154 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// An implementation of the Jump Flood algorithm by Rong and Tan
|
||||
// Source: https://www.comp.nus.edu.sg/~tants/jfa.html
|
||||
|
||||
#pragma kernel CrestInitialize
|
||||
#pragma kernel CrestExecute
|
||||
#pragma kernel CrestApply
|
||||
|
||||
#pragma multi_compile_local __ d_Crest_Inverted
|
||||
#pragma multi_compile_local __ d_Crest_Standalone
|
||||
|
||||
#include "HLSLSupport.cginc"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Constants.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.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"
|
||||
|
||||
CBUFFER_START(CrestPerMaterial)
|
||||
uint _Crest_JumpSize;
|
||||
uint _Crest_TextureSize;
|
||||
float4x4 _Crest_ProjectionToWorld;
|
||||
float _Crest_HeightOffset;
|
||||
float _Crest_WaterLevel;
|
||||
CBUFFER_END
|
||||
|
||||
// Holds scene depth for initialization.
|
||||
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 float2(m_Crest_PositiveInfinity, m_Crest_PositiveInfinity)
|
||||
|
||||
#if d_Crest_Inverted
|
||||
#define m_DepthCheck depth > 0.0
|
||||
#else
|
||||
#define m_DepthCheck depth <= 0.0
|
||||
#endif
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
bool IsUninitializedPosition(const float2 position)
|
||||
{
|
||||
return isinf(position.x);
|
||||
}
|
||||
|
||||
float2 IDtoWorld(const uint2 id, const float resolution, const float4x4 projectionToWorld)
|
||||
{
|
||||
float2 uv = (((id + 0.5) / resolution) - 0.5) * 2.0;
|
||||
return mul(projectionToWorld, float4(uv, 0.0, 1.0)).xz;
|
||||
}
|
||||
|
||||
void Initialize(const uint3 id)
|
||||
{
|
||||
float2 position = IDtoWorld(id.xy, _Crest_TextureSize, _Crest_ProjectionToWorld);
|
||||
float depth = _Crest_WaterLevel - (_Crest_Source[id.xy].x + _Crest_HeightOffset);
|
||||
|
||||
#ifndef d_Crest_Standalone
|
||||
// Add height offset.
|
||||
uint slice0; uint slice1; float alpha;
|
||||
PosToSliceIndices(position, 0, g_Crest_LodCount - 1, g_Crest_WaterScale, slice0, slice1, alpha);
|
||||
depth += lerp(Cascade::MakeLevel(slice0).SampleLevel(position), Cascade::MakeLevel(slice1).SampleLevel(position), alpha);
|
||||
#endif
|
||||
|
||||
_Crest_Target[id.xy] = m_DepthCheck ? position : m_CrestUninitializedPosition;
|
||||
}
|
||||
|
||||
void Execute(const uint3 id)
|
||||
{
|
||||
float2 nearest = _Crest_Source[id.xy];
|
||||
|
||||
const uint3 jump = uint3(_Crest_JumpSize, -(int)_Crest_JumpSize, 0);
|
||||
const bool xBounds = _Crest_TextureSize - _Crest_JumpSize > id.x;
|
||||
const bool yBounds = _Crest_TextureSize - _Crest_JumpSize > id.y;
|
||||
const bool zBounds = id.x >= _Crest_JumpSize;
|
||||
const bool wBounds = id.y >= _Crest_JumpSize;
|
||||
|
||||
float2 candidates[8];
|
||||
candidates[0] = yBounds ? _Crest_Source[id.xy + jump.zx] : nearest;
|
||||
candidates[1] = yBounds && xBounds ? _Crest_Source[id.xy + jump.xx] : nearest;
|
||||
candidates[2] = xBounds ? _Crest_Source[id.xy + jump.xz] : nearest;
|
||||
candidates[3] = xBounds && wBounds ? _Crest_Source[id.xy + jump.xy] : nearest;
|
||||
candidates[4] = wBounds ? _Crest_Source[id.xy + jump.zy] : nearest;
|
||||
candidates[5] = wBounds && zBounds ? _Crest_Source[id.xy + jump.yy] : nearest;
|
||||
candidates[6] = zBounds ? _Crest_Source[id.xy + jump.yz] : nearest;
|
||||
candidates[7] = zBounds && yBounds ? _Crest_Source[id.xy + jump.yx] : nearest;
|
||||
|
||||
const float2 position = IDtoWorld(id.xy, _Crest_TextureSize, _Crest_ProjectionToWorld);
|
||||
const float2 displacement = nearest - position;
|
||||
float distance2 = dot(displacement, displacement);
|
||||
|
||||
for (uint i = 0; i < 8; i++)
|
||||
{
|
||||
if (IsUninitializedPosition(nearest))
|
||||
{
|
||||
nearest = candidates[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
const float2 candidateDisplacement = candidates[i] - position;
|
||||
const float candidateDistance2 = dot(candidateDisplacement, candidateDisplacement);
|
||||
|
||||
if (candidateDistance2 < distance2)
|
||||
{
|
||||
nearest = candidates[i];
|
||||
distance2 = candidateDistance2;
|
||||
}
|
||||
}
|
||||
|
||||
_Crest_Target[id.xy] = nearest;
|
||||
}
|
||||
|
||||
void Apply(const uint3 id)
|
||||
{
|
||||
float2 result = _Crest_Target[id.xy];
|
||||
float2 position = IDtoWorld(id.xy, _Crest_TextureSize, _Crest_ProjectionToWorld);
|
||||
|
||||
#if d_Crest_Inverted
|
||||
float depth = _Crest_WaterLevel - (result.x + _Crest_HeightOffset);
|
||||
|
||||
#ifndef d_Crest_Standalone
|
||||
// Get depth including height offset.
|
||||
uint slice0; uint slice1; float alpha;
|
||||
PosToSliceIndices(position, 0, g_Crest_LodCount - 1, g_Crest_WaterScale, slice0, slice1, alpha);
|
||||
depth += lerp(Cascade::MakeLevel(slice0).SampleLevel(position), Cascade::MakeLevel(slice1).SampleLevel(position), alpha);
|
||||
#endif
|
||||
|
||||
// Do not overwrite positive SDF.
|
||||
if (depth > 0) return;
|
||||
#endif
|
||||
|
||||
float2 nearest = _Crest_Source[id.xy];
|
||||
float2 displacement = nearest - position;
|
||||
|
||||
float distance = length(displacement);
|
||||
|
||||
#if d_Crest_Inverted
|
||||
distance = -distance;
|
||||
#endif
|
||||
|
||||
result.y = distance;
|
||||
|
||||
_Crest_Target[id.xy] = result;
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestKernelDefault(Initialize)
|
||||
m_CrestKernelDefault(Execute)
|
||||
m_CrestKernelDefault(Apply)
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55a9b76c48b7343b2b66ed91a0619c29
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,63 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// Adds height from a provided texture. Used by Painted and Texture input modes.
|
||||
|
||||
#pragma kernel CrestExecute
|
||||
|
||||
#pragma multi_compile_local __ d_CatmullRom
|
||||
|
||||
#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/Helpers.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Filtering.hlsl"
|
||||
|
||||
m_DisplacementTexture(Texture2D, 4) _Crest_Texture;
|
||||
RWTexture2DArray<float> _Crest_Target;
|
||||
|
||||
CBUFFER_START(CrestPerMaterial)
|
||||
int _Crest_Blend;
|
||||
float _Crest_Weight;
|
||||
float2 _Crest_TextureSize;
|
||||
float2 _Crest_TexturePosition;
|
||||
float2 _Crest_TextureRotation;
|
||||
float2 _Crest_Resolution;
|
||||
CBUFFER_END
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
void Execute(uint3 id)
|
||||
{
|
||||
const Cascade cascade = Cascade::MakeLevel(id.z);
|
||||
const float2 uv = DataIDToInputUV(id.xy, cascade, _Crest_TexturePosition, _Crest_TextureRotation, _Crest_TextureSize);
|
||||
|
||||
half weight = _Crest_Weight;
|
||||
|
||||
// Feather boundaries.
|
||||
weight *= FeatherWeightFromUV(uv, 0.0);
|
||||
|
||||
// Check we are within bounds.
|
||||
if (weight <= 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if d_CatmullRom
|
||||
const float source = Utility::SampleTextureCatmullRom(_Crest_Texture, LODData_linear_clamp_sampler, uv, _Crest_Resolution).x;
|
||||
#else
|
||||
const float source = _Crest_Texture.SampleLevel(LODData_linear_clamp_sampler, uv, 0.0).x;
|
||||
#endif
|
||||
|
||||
const float target = _Crest_Target[id];
|
||||
|
||||
_Crest_Target[id] = Blend(_Crest_Blend, weight, 1.0, source, target);
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestInputKernelDefault(Execute)
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6bccbd92220dc418cacd3f17096c6b97
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,54 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#pragma kernel CrestExecute
|
||||
|
||||
#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/Helpers.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
|
||||
|
||||
Texture2D _Crest_Texture;
|
||||
RWTexture2DArray<float3> _Crest_Target;
|
||||
|
||||
CBUFFER_START(CrestPerMaterial)
|
||||
int _Crest_Blend;
|
||||
float _Crest_Weight;
|
||||
float2 _Crest_TextureSize;
|
||||
float2 _Crest_TexturePosition;
|
||||
float2 _Crest_TextureRotation;
|
||||
float _Crest_FeatherWidth;
|
||||
CBUFFER_END
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
void Execute(uint3 id)
|
||||
{
|
||||
const Cascade cascade = Cascade::MakeScattering(id.z);
|
||||
const float2 uv = DataIDToInputUV(id.xy, cascade, _Crest_TexturePosition, _Crest_TextureRotation, _Crest_TextureSize);
|
||||
|
||||
half weight = _Crest_Weight;
|
||||
|
||||
// Feather boundaries.
|
||||
weight *= FeatherWeightFromUV(uv, _Crest_FeatherWidth);
|
||||
|
||||
// Check we are within bounds.
|
||||
if (weight <= 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const half4 source = _Crest_Texture.SampleLevel(LODData_linear_clamp_sampler, uv, 0);
|
||||
const half3 target = _Crest_Target[id];
|
||||
weight *= source.a;
|
||||
|
||||
_Crest_Target[id] = Blend(_Crest_Blend, weight, 1.0, source.xyz, target);
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestInputKernelDefault(Execute)
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78d6b75ecfb664f0cbb70001b1446627
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,124 +0,0 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#pragma kernel CrestExecute
|
||||
|
||||
#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/Helpers.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Cascade.hlsl"
|
||||
|
||||
RWTexture2DArray<float2> _Crest_Target;
|
||||
|
||||
CBUFFER_START(CrestPerWaterInput)
|
||||
float3 _Crest_Position;
|
||||
float3 _Crest_Velocity;
|
||||
float _Crest_SimDeltaTime;
|
||||
float _Crest_Weight;
|
||||
float _Crest_Radius;
|
||||
float _Crest_InnerSphereOffset;
|
||||
float _Crest_InnerSphereMultiplier;
|
||||
float _Crest_LargeWaveMultiplier;
|
||||
CBUFFER_END
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
// Resolution-aware interaction falloff function, inspired by "bandfiltered step"
|
||||
// from Ottosson. Basically adding together this falloff function at different
|
||||
// scales generates a consistent result that doesn't grow into an ugly uintended
|
||||
// shape. Shadertoy with more details: https://www.shadertoy.com/view/WltBWM
|
||||
float InteractionFalloff(float a, float x)
|
||||
{
|
||||
float ax = a * x;
|
||||
float ax2 = ax * ax;
|
||||
float ax4 = ax2 * ax2;
|
||||
|
||||
return ax / (1.0 + ax2 * ax4);
|
||||
}
|
||||
|
||||
void SphereSDF(float2 offsetXZ, out float sdf, out float2 normal)
|
||||
{
|
||||
float distance = length(offsetXZ);
|
||||
sdf = distance - _Crest_Radius;
|
||||
normal = distance > 0.0001 ? offsetXZ / distance : float2(1.0, 0.0);
|
||||
}
|
||||
|
||||
void Execute(uint3 id)
|
||||
{
|
||||
const Cascade cascade = Cascade::MakeDynamicWaves(id.z);
|
||||
|
||||
if (_Crest_LargeWaveMultiplier * _Crest_Radius < cascade._Texel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float2 positionXZ = cascade.IDToWorld(id.xy);
|
||||
float2 offsetXZ = positionXZ - _Crest_Position.xz;
|
||||
|
||||
// Spherical culling. Check diameter for buffered area.
|
||||
if (length(offsetXZ) > _Crest_Radius * 4.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Feather at edges of LOD to reduce streaking without reflections.
|
||||
half weight = _Crest_Weight * FeatherWeightFromUV(cascade.WorldToUV(positionXZ).xy, 0.1);
|
||||
|
||||
// Check we are within bounds.
|
||||
if (weight <= 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float minimumWavelength = Cascade::Make(id.z)._MaximumWavelength * 0.5;
|
||||
|
||||
float sdf;
|
||||
float2 sdfNormal;
|
||||
SphereSDF(offsetXZ, sdf, sdfNormal);
|
||||
|
||||
// Push in same direction as velocity inside sphere, and opposite direction outside.
|
||||
float verticalForce = 0.0;
|
||||
{
|
||||
verticalForce = -_Crest_Velocity.y;
|
||||
|
||||
// Range / radius of interaction force
|
||||
const float a = 1.67 / minimumWavelength;
|
||||
verticalForce *= InteractionFalloff( a, sdf );
|
||||
}
|
||||
|
||||
// Push water up in direction of motion, pull down behind.
|
||||
float horizontalForce = 0.0;
|
||||
if (sdf > 0.0 || sdf < -_Crest_Radius * _Crest_InnerSphereOffset)
|
||||
{
|
||||
// Range / radius of interaction force.
|
||||
const float a = 1.43 / minimumWavelength;
|
||||
|
||||
// Invert within sphere, to balance / negate forces applied outside of sphere.
|
||||
float forceSign = sign(sdf);
|
||||
|
||||
horizontalForce = forceSign * dot(sdfNormal, _Crest_Velocity.xz) * InteractionFalloff(a, abs(sdf));
|
||||
|
||||
// If inside sphere, add an additional weight.
|
||||
if (sdf < 0.0)
|
||||
{
|
||||
horizontalForce *= _Crest_InnerSphereMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
// Add to velocity (y-channel) to accelerate water. Magic number was the default
|
||||
// value for _Strength which has been removed.
|
||||
float acceleration = weight * (verticalForce + horizontalForce) * 0.2;
|
||||
|
||||
// Helps interaction to work at different scales
|
||||
acceleration /= minimumWavelength;
|
||||
|
||||
_Crest_Target[id] = float2(_Crest_Target[id].x, _Crest_Target[id].y + acceleration * _Crest_SimDeltaTime);
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
m_CrestInputKernelDefault(Execute)
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98fb0af5d79724a2c945809b974524eb
|
||||
ComputeShaderImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user