修改水

This commit is contained in:
2026-01-01 22:00:33 +08:00
parent 040a222bd6
commit 9ceffccd39
1800 changed files with 103929 additions and 139495 deletions

View File

@@ -0,0 +1,545 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#ifndef CREST_CASCADE_INCLUDED
#define CREST_CASCADE_INCLUDED
// Fix Unity macro leaks.
#undef _Weight
#ifdef SHADER_API_PSSL
#define m_ConstantReturn const
#else
#define m_ConstantReturn
#endif
#define m_SanitizeAbsorption(x) x
#define m_SanitizeAlbedo(x) x
#define m_SanitizeAnimatedWaves(x) x
#define m_SanitizeClip(x) x
// Infinity is unsafe, as it causes NaNs if multiplied by zero.
#define m_SanitizeDepth(x) max(x, -m_FloatMaximum)
#define m_SanitizeDynamicWaves(x) x
#define m_SanitizeFlow(x) x
#define m_SanitizeFoam(x) x
#define m_SanitizeLevel(x) x
#define m_SanitizeScattering(x) x
#define m_SanitizeShadow(x) x
#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/InputsDriven.hlsl"
#define m__MakeCascade(name, source) \
static Cascade Make##name##source(uint i_Index) \
{ \
float4 perType = g_Crest_SamplingParameters##name; \
float4 perSlice = g_Crest_SamplingParametersCascade##name##source[i_Index]; \
Cascade result; \
result._Texture = g_Crest_Cascade##name##source; \
result._SamplingParameters = g_Crest_SamplingParametersCascade##name##source; \
result._Index = i_Index; \
result._PositionSnapped = perSlice.xy; \
result._Texel = perSlice.z; \
result._Resolution = perType.y; \
result._OneOverResolution = perType.z; \
result._Count = perType.x; \
return result; \
} \
#define m_MakeCascadeCopy(name) \
static Cascade Make##name(uint i_Index, Cascade i_Cascade) \
{ \
float4 perType = g_Crest_SamplingParameters##name; \
float4 perSlice = i_Cascade._SamplingParameters[i_Index]; \
Cascade result; \
result._Texture = i_Cascade._Texture; \
result._SamplingParameters = i_Cascade._SamplingParameters; \
result._Index = i_Index; \
result._PositionSnapped = perSlice.xy; \
result._Texel = perSlice.z; \
result._Resolution = perType.y; \
result._OneOverResolution = perType.z; \
result._Count = perType.x; \
return result; \
}
#define m__MakeCascadeShared(source) \
static Cascade Make##source(uint i_Index) \
{ \
const float4 perAll = g_Crest_CascadeData##source[i_Index]; \
Cascade result; \
result._Index = i_Index; \
result._Scale = perAll.x; \
result._Weight = perAll.y; \
result._MaximumWavelength = perAll.z; \
return result; \
}
#define m_MakeCascade(name) m__MakeCascade(name,)
#define m_MakeCascadePrevious(name) m__MakeCascade(name, Source)
#define m_MakeCascadeShared m__MakeCascadeShared()
#define m_MakeCascadeSharedPrevious m__MakeCascadeShared(Source)
#define m_Sample(name, type, swizzle) \
type Sample##name(const float2 i_Position) m_ConstantReturn \
{ \
type result = Sample(i_Position)swizzle; \
result = m_Sanitize##name(result); \
return result; \
} \
type Sample##name(const float3 i_UV) m_ConstantReturn \
{ \
return Sample(i_UV)swizzle; \
} \
type Sample##name(const uint2 i_ID) m_ConstantReturn \
{ \
return Sample(i_ID)swizzle; \
} \
type Sample##name##Overflow(const float2 i_Position, const float i_Border) m_ConstantReturn \
{ \
type result = 0.0; \
const float3 uv = WorldToUV(i_Position); \
const half2 r = abs(uv.xy - 0.5); \
const half rMax = 0.5 - _OneOverResolution * i_Border; \
if (max(r.x, r.y) <= rMax) \
{ \
result = Sample##name(uv); \
} \
else if (_Index < _Count) \
{ \
const Cascade cascade = Cascade::Make##name(_Index + 1, this); \
const float3 uv = cascade.WorldToUV(i_Position); \
const half2 r = abs(uv.xy - 0.5); \
const half rMax = 0.5 - cascade._OneOverResolution * i_Border; \
if (max(r.x, r.y) <= rMax) \
{ \
result = Sample##name(uv); \
} \
} \
return result; \
} \
type Sample##name##Overflow(const float3 i_UV, const float i_Border) m_ConstantReturn \
{ \
type result = 0.0; \
const half2 r = abs(i_UV.xy - 0.5); \
const half rMax = 0.5 - _OneOverResolution * i_Border; \
if (max(r.x, r.y) <= rMax) \
{ \
result = Sample##name(i_UV); \
} \
else if (_Index < _Count) \
{ \
const Cascade cascade = Cascade::Make##name(_Index + 1, this); \
const float3 uv = cascade.WorldToUV(UVToWorld(i_UV)); \
const half2 r = abs(uv.xy - 0.5); \
const half rMax = 0.5 - cascade._OneOverResolution * i_Border; \
if (max(r.x, r.y) <= rMax) \
{ \
result = Sample##name(uv); \
} \
} \
return result; \
}
#define m_SampleWeighted(name, type) \
void Sample##name(const float2 i_Position, const float i_Weight, inout type io_##name) m_ConstantReturn \
{ \
io_##name += Sample##name(i_Position) * i_Weight; \
} \
void Sample##name(const float3 i_UV, const float i_Weight, inout type io_##name) m_ConstantReturn \
{ \
io_##name += Sample##name(i_UV) * i_Weight; \
} \
void Sample##name##Overflow(const float2 i_Position, const float i_Border, const float i_Weight, inout type io_##name) m_ConstantReturn \
{ \
io_##name += Sample##name##Overflow(i_Position, i_Border) * i_Weight; \
}
m_CrestNameSpace
struct Cascade
{
Texture2DArray _Texture;
float _Index;
float2 _PositionSnapped;
float _Resolution;
float _Count;
float _OneOverResolution;
float _Texel;
float _MaximumWavelength;
float _Scale;
float _Weight;
// For copy constructor.
float4 _SamplingParameters[MAX_LOD_COUNT];
m_MakeCascadeShared
m_MakeCascadeSharedPrevious
static Cascade Make(const uint i_Index, bool i_Previous)
{
const float4 perAll = i_Previous ? g_Crest_CascadeDataSource[i_Index] : g_Crest_CascadeData[i_Index];
Cascade result;
result._Index = i_Index;
result._Scale = perAll.x;
result._Weight = perAll.y;
result._MaximumWavelength = perAll.z;
return result;
}
m_MakeCascade(Absorption)
m_MakeCascadeCopy(Absorption)
m_MakeCascade(Albedo)
m_MakeCascadeCopy(Albedo)
m_MakeCascade(AnimatedWaves)
m_MakeCascadeCopy(AnimatedWaves)
m_MakeCascadePrevious(AnimatedWaves)
m_MakeCascade(Clip)
m_MakeCascadeCopy(Clip)
m_MakeCascade(Depth)
m_MakeCascadeCopy(Depth)
m_MakeCascade(DynamicWaves)
m_MakeCascadeCopy(DynamicWaves)
m_MakeCascadePrevious(DynamicWaves)
m_MakeCascade(Flow)
m_MakeCascadeCopy(Flow)
m_MakeCascade(Foam)
m_MakeCascadeCopy(Foam)
m_MakeCascadePrevious(Foam)
m_MakeCascade(Level)
m_MakeCascadeCopy(Level)
m_MakeCascade(Scattering)
m_MakeCascadeCopy(Scattering)
m_MakeCascade(Shadow)
m_MakeCascadeCopy(Shadow)
m_MakeCascadePrevious(Shadow)
// Convert compute shader id to uv texture coordinates
float3 IDToUV(const uint2 i_ID) m_ConstantReturn
{
return float3((i_ID + 0.5) / _Resolution, _Index);
}
float2 UVToWorld(const float3 i_UV) m_ConstantReturn
{
return _Texel * _Resolution * (i_UV.xy - 0.5) + _PositionSnapped;
}
float3 WorldToUV(const float2 i_Position) m_ConstantReturn
{
return float3((i_Position - _PositionSnapped) / (_Texel * _Resolution) + 0.5, _Index);
}
float2 IDToWorld(const uint2 i_ID) m_ConstantReturn
{
return UVToWorld(IDToUV(i_ID));
}
bool IsOutOfBounds(float2 uv, float offset) m_ConstantReturn
{
const half2 r = abs(uv - 0.5);
const half rMax = 0.5 - _OneOverResolution * offset;
return max(r.x, r.y) > rMax;
}
half4 Sample(const float3 i_UV) m_ConstantReturn
{
return _Texture.SampleLevel(LODData_linear_clamp_sampler, i_UV, 0.0);
}
half4 Sample(const Texture2DArray i_Texture, const float3 i_UV) m_ConstantReturn
{
return i_Texture.SampleLevel(LODData_linear_clamp_sampler, i_UV, 0.0);
}
half4 Sample(const float2 i_Position) m_ConstantReturn
{
return Sample(WorldToUV(i_Position));
}
half4 Sample(const Texture2DArray i_Texture, const float2 i_Position) m_ConstantReturn
{
return Sample(i_Texture, WorldToUV(i_Position));
}
half4 Sample(const uint2 i_ID) m_ConstantReturn
{
return Sample(IDToUV(i_ID));
}
half4 Sample(const Texture2DArray i_Texture, const uint2 i_ID) m_ConstantReturn
{
return Sample(i_Texture, IDToUV(i_ID));
}
float3 Internal_WrapToNextSlice(float3 i_uv, float i_overflowed) m_ConstantReturn
{
// Next slice is twice the size so half the coordinates to match position.
float overflow = 0.5 * i_overflowed;
i_uv = float3((i_uv.xy - overflow) * (1.0 - overflow) + overflow, i_uv.z + i_overflowed);
return i_uv;
}
// Wraps to next slice if coordinates outside of range.
float3 WrapToNextSlice(float3 i_uv) m_ConstantReturn
{
return Internal_WrapToNextSlice(i_uv, any(i_uv.xy > 1.0) || any(i_uv.xy < 0.0));
}
// Wraps to next slice if coordinates outside of range.
float3 WrapToNextSlice(float3 i_uv, float i_depth) m_ConstantReturn
{
return Internal_WrapToNextSlice(i_uv, any(i_uv.xy > 1.0) || any(i_uv.xy < 0.0) && i_uv.z + 1.0 < i_depth);
}
m_Sample(Absorption, half3, .xyz)
m_SampleWeighted(Absorption, half3)
m_Sample(Albedo, half4, )
m_SampleWeighted(Albedo, half4)
m_Sample(AnimatedWaves, half4, )
m_SampleWeighted(AnimatedWaves, float4) // Use float because parameter is position
m_Sample(Clip, half, .x)
m_SampleWeighted(Clip, half)
m_Sample(Depth, half2, .xy)
m_SampleWeighted(Depth, half2)
m_Sample(DynamicWaves, half2, .xy)
m_Sample(Flow, half2, .xy)
m_SampleWeighted(Flow, half2)
m_Sample(Foam, half, .x)
m_SampleWeighted(Foam, half)
m_Sample(Level, half, .x)
m_SampleWeighted(Level, half)
m_Sample(Scattering, half3, .xyz)
m_SampleWeighted(Scattering, half3)
m_Sample(Shadow, half2, .xy)
m_SampleWeighted(Shadow, half2)
float3 SampleDisplacement(const float2 i_Position) m_ConstantReturn
{
float4 position = SampleAnimatedWaves(i_Position);
position.y += position.w;
return position.xyz;
}
void SampleDisplacement(const float2 i_Position, const float i_Weight, inout float3 io_Position) m_ConstantReturn
{
io_Position += SampleDisplacement(i_Position).xyz * i_Weight;
}
half3 SampleWaveDisplacement(const float2 i_Position) m_ConstantReturn
{
return SampleAnimatedWaves(i_Position).xyz;
}
half3 SampleWaveDisplacement(const float3 i_UV) m_ConstantReturn
{
return SampleAnimatedWaves(i_UV).xyz;
}
half4 __SampleDisplacements(const float2 i_Position, out float3 o_DisplacementX, out float3 o_DisplacementZ) m_ConstantReturn
{
const float3 uv = WorldToUV(i_Position);
const half4 displacement = SampleAnimatedWaves(uv);
const float3 dd = float3(_OneOverResolution, 0.0, _Texel);
o_DisplacementX = dd.zyy + SampleWaveDisplacement(uv + dd.xyy);
o_DisplacementZ = dd.yyz + SampleWaveDisplacement(uv + dd.yxy);
return displacement;
}
void SampleDisplacement(const float2 i_Position, const float i_Weight, inout float3 io_Position, inout half2 io_Derivatives, inout half io_LevelOffset) m_ConstantReturn
{
float3 uv = WorldToUV(i_Position);
float4 position = SampleAnimatedWaves(uv);
io_LevelOffset += position.w * i_Weight;
io_Position += position.xyz * i_Weight;
// Derivatives
{
// Compute derivative of water level - needed to get base normal of water. Water
// normal, normal map etc is then added to base normal.
const float2 dd = float2(_OneOverResolution, 0.0);
const float xOffset = SampleAnimatedWaves(uv + dd.xyy).w;
const float zOffset = SampleAnimatedWaves(uv + dd.yxy).w;
// TODO: Is weight in correct position?
io_Derivatives.x += i_Weight * (xOffset - position.w) / _Texel;
io_Derivatives.y += i_Weight * (zOffset - position.w) / _Texel;
}
}
void SampleDisplacement(const float2 i_Position, const float i_Weight, inout float3 io_Position, inout half2 io_Derivatives) m_ConstantReturn
{
half offset = 0.0;
SampleDisplacement(i_Position, i_Weight, io_Position, io_Derivatives, offset);
io_Position.y += offset;
}
half3 SampleDisplacement(const float2 i_Position, out half o_Determinent) m_ConstantReturn
{
float3 xDisplacement; float3 zDisplacement;
half4 displacement = __SampleDisplacements(i_Position, xDisplacement, zDisplacement);
o_Determinent = __ComputeDisplacementDeterminant(displacement.xyz, xDisplacement, zDisplacement);
displacement.y += displacement.w;
return displacement.xyz;
}
half __ComputeDisplacementDeterminant(half3 i_Displacement, float3 i_DisplacementX, float3 i_DisplacementZ) m_ConstantReturn
{
const float2x2 jacobian = (float4(i_DisplacementX.xz, i_DisplacementZ.xz) - i_Displacement.xzxz) / _Texel;
// Determinant is < 1 for pinched, < 0 for overlap/inversion and > 1 for stretched.
return determinant(jacobian);
}
half2 __ComputeDisplacementNormals(half3 i_Displacement, float3 i_DisplacementX, float3 i_DisplacementZ) m_ConstantReturn
{
float3 xProduct = cross(i_DisplacementZ - i_Displacement, i_DisplacementX - i_Displacement);
// Situation could arise where cross returns 0, prob when arguments are two aligned vectors. This
// resulted in NaNs and flashing screen in HDRP. Force normal to point upwards as the only time
// it should point downwards is for underwater (handled elsewhere) or in surface inversions which
// should not happen for well tweaked waves, and look broken anyway.
xProduct.y = max(xProduct.y, 0.0001);
return normalize(xProduct).xz;
}
// TODO: Rename
void SampleNormals(const float2 i_Position, const float i_Weight, inout half2 io_Normal, inout half io_Determinant) m_ConstantReturn
{
float3 xDisplacement; float3 zDisplacement;
half3 displacement = __SampleDisplacements(i_Position, xDisplacement, zDisplacement).xyz;
io_Normal += __ComputeDisplacementNormals(displacement, xDisplacement, zDisplacement) * i_Weight;
io_Determinant += __ComputeDisplacementDeterminant(displacement, xDisplacement, zDisplacement) * i_Weight;
}
half SampleSceneHeight(const float2 i_Position) m_ConstantReturn
{
return SampleDepth(i_Position).x;
}
void SampleSceneHeight(const float2 i_Position, const float i_Weight, inout half io_Height) m_ConstantReturn
{
io_Height += SampleSceneHeight(i_Position) * i_Weight;
}
half SampleShorelineDistance(const float2 i_Position) m_ConstantReturn
{
return Sample(i_Position).y;
}
half SampleShorelineDistance(const float3 i_UV) m_ConstantReturn
{
return Sample(i_UV).y;
}
half SampleShorelineDistance(const uint2 i_ID) m_ConstantReturn
{
return Sample(i_ID).y;
}
void SampleShorelineDistance(const float2 i_Position, const float i_Weight, inout half io_Distance) m_ConstantReturn
{
io_Distance += SampleShorelineDistance(i_Position) * i_Weight;
}
half SampleSignedDepthFromSeaLevel(const float2 i_Position) m_ConstantReturn
{
return g_Crest_WaterCenter.y - SampleSceneHeight(i_Position);
}
half2 SampleSignedDepthFromSeaLevelAndDistance(const float2 i_Position) m_ConstantReturn
{
half2 value = SampleDepth(i_Position);
value.x = g_Crest_WaterCenter.y - value.x;
return value;
}
void SampleSignedDepthFromSeaLevel(const float2 i_Position, const float i_Weight, inout half io_Depth) m_ConstantReturn
{
io_Depth += (g_Crest_WaterCenter.y - SampleSceneHeight(i_Position)) * i_Weight;
}
// Perform iteration to invert the displacement vector field - find position that displaces to query position.
float2 SampleInvertedDisplacement(const float2 i_Position) m_ConstantReturn
{
float2 inverted = i_Position;
for (uint i = 0; i < 4; i++)
{
const float2 displacement = SampleAnimatedWaves(inverted).xz;
const float2 error = (inverted + displacement) - i_Position;
inverted -= error;
}
return inverted;
}
half3 SampleDisplacementFromUndisplaced(const float2 i_Position) m_ConstantReturn
{
return SampleDisplacement(SampleInvertedDisplacement(i_Position));
}
half3 SampleDynamicWavesDisplacement(const float2 i_Position, const float i_HorizontalDisplace, const float i_DisplaceClamp) m_ConstantReturn
{
const float3 uv = WorldToUV(i_Position);
return SampleDynamicWavesDisplacement(uv, i_HorizontalDisplace, i_DisplaceClamp);
}
half3 SampleDynamicWavesDisplacement(const float3 i_UV, const float i_HorizontalDisplace, const float i_DisplaceClamp) m_ConstantReturn
{
const float3 uv = i_UV;
half3 displacement = 0.0;
displacement.y = Sample(uv).x;
const float2 invRes = float2(_OneOverResolution, 0.0);
const half waveSimY_px = Sample(uv + invRes.xyy).x;
const half waveSimY_nx = Sample(uv - invRes.xyy).x;
const half waveSimY_pz = Sample(uv + invRes.yxy).x;
const half waveSimY_nz = Sample(uv - invRes.yxy).x;
// Compute displacement from gradient of water surface - discussed in issue #18 and then in issue #47.
// For gerstner waves, horizontal displacement is proportional to derivative of
// vertical displacement multiplied by the wavelength.
const float wavelength_mid = 2.0 * _Texel * 1.5;
const float wavevector = 2.0 * 3.14159 / wavelength_mid;
const float2 dydx = (float2(waveSimY_px, waveSimY_pz) - float2(waveSimY_nx, waveSimY_nz)) / (2.0 * _Texel);
displacement.xz = i_HorizontalDisplace * dydx / wavevector;
const float maxDisp = _Texel * i_DisplaceClamp;
displacement.xz = clamp(displacement.xz, -maxDisp, maxDisp);
return displacement;
}
};
float2 DataIDToInputUV
(
const float2 i_ID,
const Cascade i_Cascade,
const float2 i_Position,
const float2 i_Rotation,
const float2 i_Size
)
{
const float2 position = i_Cascade.IDToWorld(i_ID);
float2 uv = (position - i_Position) / i_Size;
// Clockwise transform rotation.
uv = uv.x * float2(i_Rotation.y, -i_Rotation.x) + uv.y * i_Rotation;
uv += 0.5;
return uv;
}
m_CrestNameSpaceEnd
#undef m__MakeCascade
#undef m_MakeCascade
#undef m_MakeCascadePrevious
#undef m_Sample
#undef m_SampleWeighted
#undef m_ComputeDepth
#endif // CREST_CASCADE_INCLUDED

View File

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

View File

@@ -0,0 +1,72 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#ifndef CREST_CONSTANTS_H
#define CREST_CONSTANTS_H
#define m_CrestBlendNone 0
#define m_CrestBlendAdditive 1
#define m_CrestBlendMinimum 2
#define m_CrestBlendMaximum 3
#define m_CrestBlendAlpha 4
#define m_Crest_PositiveInfinity asfloat(0x7F800000)
#define m_Crest_NegativeInfinity asfloat(0xFF800000)
// Was 0.001, but caused prominent seams for sensitive data like water level.
// 0.00001 worked, but not worth the miniscule saving (in theory). It would require
// testing across various LOD quality settings.
#define m_CrestSampleLodThreshold 0.0
// NOTE: these MUST match the values in PropertyWrapper.cs
#define THREAD_GROUP_SIZE_X 8
#define THREAD_GROUP_SIZE_Y 8
// NOTE: This must match the value in LodDataMgr.cs, as it is used to allow the
// C# code to check if any parameters are within the MAX_LOD_COUNT limits
#define MAX_LOD_COUNT 15
// How light is attenuated deep in water
#define DEPTH_OUTSCATTER_CONSTANT 0.25
// NOTE: Must match k_DepthBaseline in LodDataMgrSeaFloorDepth.cs.
// Bias water floor depth so that default (0) values in texture are not interpreted as shallow and generating foam everywhere
#define CREST_WATER_DEPTH_BASELINE m_Crest_PositiveInfinity
#define k_Crest_MaximumWaveAttenuationDepth 1000.0
// Soft shadows is red, hard shadows is green.
#define CREST_SHADOW_INDEX_SOFT 0
#define CREST_SHADOW_INDEX_HARD 1
#define k_Crest_MaximumShadowJitter 32.0
#define CREST_SSS_MAXIMUM 0.6
#define CREST_SSS_RANGE 0.12
// Note: Must match k_MaskBelowSurfaceCull in UnderwaterRenderer.Mask.cs.
// Fog rendered from below and before transparents and water tile is culled.
#define CREST_MASK_BELOW_SURFACE_CULLED -2.0
// Note: Must match k_MaskBelowSurface in UnderwaterRenderer.Mask.cs.
// Fog rendered from below.
#define CREST_MASK_BELOW_SURFACE -1.0
// Fog rendered from above.
#define CREST_MASK_ABOVE_SURFACE 1.0
// Normally discard, but keep. Used by negative volumes.
#define CREST_MASK_ABOVE_SURFACE_KEPT 2.0
#define CREST_MASK_BELOW_SURFACE_KEPT -2.0
// No mask. Used by meniscus when using volumes.
#define CREST_MASK_NONE 0.0
// No fog. Nicer wording for comparisons.
#define CREST_MASK_NO_FOG 0.0
// The maximum distance the meniscus will be rendered. Only valid when rendering underwater from geometry. The value is
// used to scale the meniscus as it is calculate using a pixel offset which can make the meniscus large at a distance.
#define MENISCUS_MAXIMUM_DISTANCE 15.0
#if defined(STEREO_INSTANCING_ON) || defined(STEREO_MULTIVIEW_ON)
#define CREST_HANDLE_XR 1
#else
#define CREST_HANDLE_XR 0
#endif
#endif // CREST_CONSTANTS_H

View File

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

View File

@@ -0,0 +1,48 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#ifndef CREST_FLOW_INCLUDED
#define CREST_FLOW_INCLUDED
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"
m_CrestNameSpace
struct Flow
{
float _Offset0;
float _Weight0;
float _Offset1;
float _Weight1;
float _Period;
half2 _Flow;
static Flow Make
(
const half2 i_Flow,
const float i_Time,
const float i_Period = 1.0
)
{
const float Period = i_Period;
const float HalfPeriod = Period * 0.5;
const float Offset0 = fmod(i_Time, Period);
float Weight0 = Offset0 / HalfPeriod;
if (Weight0 > 1.0) Weight0 = 2.0 - Weight0;
const float Offset1 = fmod(i_Time + HalfPeriod, Period);
const float Weight1 = 1.0 - Weight0;
Flow flow;
flow._Offset0 = Offset0;
flow._Weight0 = Weight0;
flow._Offset1 = Offset1;
flow._Weight1 = Weight1;
flow._Period = Period;
flow._Flow = i_Flow;
return flow;
}
};
m_CrestNameSpaceEnd
#endif // CREST_FLOW_INCLUDED

View File

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

View File

@@ -0,0 +1,55 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// GLOBALs - we're allowed to use these anywhere.
#ifndef CREST_WATER_GLOBALS_H
#define CREST_WATER_GLOBALS_H
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings.Crest.hlsl"
SamplerState LODData_linear_clamp_sampler;
SamplerState LODData_point_clamp_sampler;
SamplerState sampler_Crest_linear_repeat;
CBUFFER_START(CrestPerFrame)
float3 g_Crest_WaterCenter;
float g_Crest_WaterScale;
float g_Crest_Time;
float g_Crest_LodCount;
int g_Crest_LodChange;
float g_Crest_MeshScaleLerp;
float g_Crest_ClipByDefault;
float g_Crest_LodAlphaBlackPointFade;
float g_Crest_LodAlphaBlackPointWhitePointFade;
// Hack - due to SV_IsFrontFace occasionally coming through as true for
// backfaces, add a param here that forces water to be in undrwater state. I
// think the root cause here might be imprecision or numerical issues at water
// tile boundaries, although I'm not sure why cracks are not visible in this case.
int g_Crest_ForceUnderwater;
float3 g_Crest_PrimaryLightDirection;
float3 g_Crest_PrimaryLightIntensity;
float g_Crest_DynamicSoftShadowsFactor;
bool g_Crest_SampleAbsorptionSimulation;
bool g_Crest_SampleScatteringSimulation;
// Motion Vector Parameters
float g_Crest_WaterScaleChange;
float3 g_Crest_WaterCenterDelta;
// Shifting Origin
#if (CREST_SHIFTING_ORIGIN != 0)
float3 g_Crest_ShiftingOriginOffset;
#endif
// Portals
#if (CREST_PORTALS != 0)
int _Crest_Portal;
#endif
CBUFFER_END
#endif

View File

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

View File

@@ -0,0 +1,127 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// LOD data - data, samplers and functions associated with LODs
#ifndef CREST_WATER_HELPERS_H
#define CREST_WATER_HELPERS_H
#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/InputsDriven.hlsl"
m_CrestNameSpace
#define m_Blend(type) \
type Blend(const int i_Blend, const float i_Alpha, const float i_DeltaTime, const type i_Source, const type i_Target) \
{ \
switch (i_Blend) \
{ \
case m_CrestBlendMinimum: \
return min(i_Target, i_Source * i_Alpha); \
case m_CrestBlendMaximum: \
return max(i_Target, i_Source * i_Alpha); \
case m_CrestBlendAdditive: \
return i_Target + i_Source * i_Alpha * i_DeltaTime; \
case m_CrestBlendAlpha: \
return lerp(i_Target, i_Source, i_Alpha); \
case m_CrestBlendNone: \
default: \
return i_Source * i_Alpha; \
} \
} \
m_Blend(float)
m_Blend(float2)
m_Blend(float3)
m_Blend(float4)
uint PositionToSliceIndex
(
const float2 i_PositionXZ,
const float i_MinimumSlice,
const float i_WaterScale0
)
{
const float2 offsetFromCenter = abs(i_PositionXZ - g_Crest_WaterCenter.xz);
const float taxicab = max(offsetFromCenter.x, offsetFromCenter.y);
const float radius0 = i_WaterScale0;
float sliceNumber = log2(max(taxicab / radius0, 1.0));
// Don't use last slice - this is a "transition" slice used to cross fade waves
// between LOD resolutions to avoid pops.
sliceNumber = clamp(sliceNumber, i_MinimumSlice, g_Crest_LodCount - 2.0);
return floor(sliceNumber);
}
void PosToSliceIndices
(
const float2 worldXZ,
const float minSlice,
const float maxSlice,
const float waterScale0,
out uint slice0,
out uint slice1,
out float lodAlpha
)
{
const float2 offsetFromCenter = abs(worldXZ - g_Crest_WaterCenter.xz);
const float taxicab = max(offsetFromCenter.x, offsetFromCenter.y);
const float radius0 = waterScale0;
float sliceNumber = log2( max( taxicab / radius0, 1.0 ) );
sliceNumber = clamp( sliceNumber, minSlice, maxSlice );
lodAlpha = frac(sliceNumber);
// Fixes artefact with DX12 & Vulkan. Likely a compiler bug.
// Sampling result appears to be all over the place.
slice0 = floor(sliceNumber) + 0.01;
slice1 = slice0 + 1;
// lod alpha is remapped to ensure patches weld together properly. patches can vary significantly in shape (with
// strips added and removed), and this variance depends on the base density of the mesh, as this defines the strip width.
// using .15 as black and .85 as white should work for base mesh density as low as 16.
const float BLACK_POINT = 0.15, WHITE_POINT = 0.85;
lodAlpha = saturate((lodAlpha - BLACK_POINT) / (WHITE_POINT - BLACK_POINT));
if (slice0 == 0)
{
// blend out lod0 when viewpoint gains altitude. we're using the global g_Crest_MeshScaleLerp so check for LOD0 is necessary
lodAlpha = min(lodAlpha + g_Crest_MeshScaleLerp, 1.0);
}
}
bool IsUnderwater(const bool i_FrontFace, const int i_ForceUnderwater)
{
// We are well below water.
if (i_ForceUnderwater == 1)
{
return true;
}
// We are well above water.
if (i_ForceUnderwater == 2)
{
return false;
}
return !i_FrontFace;
}
float FeatherWeightFromUV(const float2 i_uv, const half i_featherWidth)
{
float2 offset = abs(i_uv - 0.5);
float r_l1 = max(offset.x, offset.y) - (0.5 - i_featherWidth);
if (i_featherWidth > 0.0) r_l1 /= i_featherWidth;
float weight = saturate(1.0 - r_l1);
return weight;
}
bool WithinUV(const float2 i_UV)
{
const float2 d = abs(i_UV - 0.5);
return max(d.x, d.y) <= 0.5;
}
m_CrestNameSpaceEnd
#endif // CREST_WATER_HELPERS_H

View File

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

View File

@@ -0,0 +1,74 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// Anything marked as "Source" is from the previous frame.
#ifndef CREST_INPUTS_DRIVEN_H
#define CREST_INPUTS_DRIVEN_H
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Constants.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"
CBUFFER_START(CrestChunkInstanceData)
uint _Crest_LodIndex;
float _Crest_ChunkMeshScaleAlpha;
float _Crest_ChunkMeshScaleAlphaSource;
float _Crest_ChunkGeometryGridWidth;
float _Crest_ChunkGeometryGridWidthSource;
float _Crest_ChunkFarNormalsWeight;
float2 _Crest_ChunkNormalScrollSpeed;
CBUFFER_END
Texture2DArray g_Crest_CascadeAbsorption;
m_DisplacementTexture(Texture2DArray, 4) g_Crest_CascadeAnimatedWaves;
m_DisplacementTexture(Texture2DArray, 4) g_Crest_CascadeAnimatedWavesSource;
Texture2DArray g_Crest_CascadeDepth;
m_DisplacementTexture(Texture2DArray, 4) g_Crest_CascadeLevel;
Texture2DArray g_Crest_CascadeClip;
Texture2DArray g_Crest_CascadeFoam;
Texture2DArray g_Crest_CascadeFoamSource;
Texture2DArray g_Crest_CascadeFlow;
Texture2DArray g_Crest_CascadeDynamicWaves;
Texture2DArray g_Crest_CascadeDynamicWavesSource;
Texture2DArray g_Crest_CascadeScattering;
Texture2DArray g_Crest_CascadeShadow;
Texture2DArray g_Crest_CascadeShadowSource;
Texture2DArray g_Crest_CascadeAlbedo;
CBUFFER_START(CrestLodData)
// Cascade Data: Scale, Weight, MaximumWavelength, 0
float4 g_Crest_CascadeData[MAX_LOD_COUNT];
float4 g_Crest_CascadeDataSource[MAX_LOD_COUNT];
// Sampling Parameters: LodCount, Resolution, OneOverResolution, 0
// Sampling Parameters (Cascade): SnappedPositionX, SnappedPositionZ, TexelWidth, 0
float4 g_Crest_SamplingParametersAbsorption;
float4 g_Crest_SamplingParametersCascadeAbsorption[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersAlbedo;
float4 g_Crest_SamplingParametersCascadeAlbedo[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersAnimatedWaves;
float4 g_Crest_SamplingParametersCascadeAnimatedWaves[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersCascadeAnimatedWavesSource[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersClip;
float4 g_Crest_SamplingParametersCascadeClip[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersDepth;
float4 g_Crest_SamplingParametersCascadeDepth[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersDynamicWaves;
float4 g_Crest_SamplingParametersCascadeDynamicWaves[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersCascadeDynamicWavesSource[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersFlow;
float4 g_Crest_SamplingParametersCascadeFlow[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersFoam;
float4 g_Crest_SamplingParametersCascadeFoam[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersCascadeFoamSource[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersLevel;
float4 g_Crest_SamplingParametersCascadeLevel[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersScattering;
float4 g_Crest_SamplingParametersCascadeScattering[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersShadow;
float4 g_Crest_SamplingParametersCascadeShadow[MAX_LOD_COUNT];
float4 g_Crest_SamplingParametersCascadeShadowSource[MAX_LOD_COUNT];
CBUFFER_END
#endif // CREST_INPUTS_DRIVEN_H

View File

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

View File

@@ -0,0 +1,72 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#ifndef CREST_MACROS_H
#define CREST_MACROS_H
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings.Crest.hlsl"
#define m_CrestNameSpace namespace WaveHarmonic { namespace Crest {
#define m_CrestNameSpaceEnd } }
#define m_Crest WaveHarmonic::Crest
#define m_FloatMaximum 3.402823466e+38
#if (CREST_FULL_PRECISION_DISPLACEMENT != 0)
#define m_DisplacementTexture(texture, components) texture<float##components>
#else
#define m_DisplacementTexture(texture, components) texture
#endif
#define m_CrestVertex \
m_Crest::Varyings Vertex(m_Crest::Attributes i_Input) \
{ \
return m_Crest::Vertex(i_Input); \
}
#define m_CrestFragment(type) \
type Fragment(m_Crest::Varyings i_Input) : SV_Target \
{ \
return m_Crest::Fragment(i_Input); \
}
#define m_CrestFragmentWithFrontFace(type) \
type Fragment(m_Crest::Varyings i_Input, const bool i_IsFrontFace : SV_IsFrontFace) : SV_Target \
{ \
return m_Crest::Fragment(i_Input, i_IsFrontFace); \
}
#define m_CrestKernel(name) \
void Crest##name(uint3 id : SV_DispatchThreadID) \
{ \
m_Crest::name(id); \
}
#define m_CrestKernelVariant(name, variant) \
void Crest##name##variant(uint3 id : SV_DispatchThreadID) \
{ \
m_Crest::name(id); \
}
#define m_CrestKernelDefault(name) \
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] \
void Crest##name(uint3 id : SV_DispatchThreadID) \
{ \
m_Crest::name(id); \
}
#define m_CrestInputKernel(name) \
void Crest##name(uint3 id : SV_DispatchThreadID) \
{ \
m_Crest::name(uint3(id.xy, g_Crest_LodCount - 1 - id.z)); \
}
#define m_CrestInputKernelDefault(name) \
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] \
void Crest##name(uint3 id : SV_DispatchThreadID) \
{ \
m_Crest::name(uint3(id.xy, g_Crest_LodCount - 1 - id.z)); \
}
#endif // CREST_MACROS_H

View File

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

View File

@@ -0,0 +1,16 @@
//
// This file was automatically generated. Please don't edit by hand. Execute Editor command [ Edit > Rendering > Generate Shader Includes ] instead
//
#ifndef SETTINGS_CREST_HLSL
#define SETTINGS_CREST_HLSL
//
// WaveHarmonic.Crest.Editor.ShaderSettings: static fields
//
#define CREST_PORTALS (0)
#define CREST_SHIFTING_ORIGIN (0)
#define CREST_SHADOWS_BUILT_IN_RENDER_PIPELINE (1)
#define CREST_FULL_PRECISION_DISPLACEMENT (1)
#endif

View File

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

View File

@@ -0,0 +1,69 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// The const keyword for PSSL solves the following:
// > Shader error in '<Shader>': Program '<Program>', member function '<FunctionName>' not viable: 'this' argument has
// > type '<Type> const', but function is not marked const
// This appears to be PSSL only feature as the fix throws a compiler error elsewhere (comprehensive test not done). I
// tried putting const at the beginning of the function signature which compiles but did not solve the problem on PSSL
// so must be different.
#ifndef CREST_TEXTURE_INCLUDED
#define CREST_TEXTURE_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/Globals.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/InputsDriven.hlsl"
#ifdef SHADER_API_PSSL
#define m_ConstantReturn const
#else
#define m_ConstantReturn
#endif
m_CrestNameSpace
struct TiledTexture
{
Texture2D _texture;
SamplerState _sampler;
half _size;
half _scale;
half _speed;
float _texel;
static TiledTexture Make
(
in const Texture2D i_texture,
in const SamplerState i_sampler,
in const float4 i_size,
in const half i_scale,
in const half i_speed
)
{
TiledTexture tiledTexture;
tiledTexture._texture = i_texture;
tiledTexture._sampler = i_sampler;
tiledTexture._scale = i_scale;
tiledTexture._speed = i_speed;
// Safely assume a square texture.
tiledTexture._size = i_size.z;
tiledTexture._texel = i_size.x;
return tiledTexture;
}
half4 Sample(float2 uv) m_ConstantReturn
{
return SAMPLE_TEXTURE2D(_texture, _sampler, uv);
}
half4 SampleLevel(float2 uv, float lod) m_ConstantReturn
{
return SAMPLE_TEXTURE2D_LOD(_texture, _sampler, uv, lod);
}
};
m_CrestNameSpaceEnd
#endif // CREST_TEXTURE_INCLUDED

View File

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

View File

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

View File

@@ -0,0 +1,74 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// Helpers that will only be used for shaders (eg depth, lighting etc).
#ifndef d_WaveHarmonic_Utility_Depth
#define d_WaveHarmonic_Utility_Depth
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Macros.hlsl"
// Silence Unity errors in SG editor.
#ifdef SHADERGRAPH_PREVIEW
#define LOAD_DEPTH_TEXTURE_X(a, b) 0
#define TEXTURE2D_X(t) Texture2D t
#else
#define LOAD_DEPTH_TEXTURE_X(textureName, coord2) LOAD_TEXTURE2D_X(textureName, coord2).r
#endif
m_UtilityNameSpace
// Taken from:
// https://www.cyanilux.com/tutorials/depth/#depth-output
float LinearDepthToNonLinear(float depth, float4 zBufferParameters)
{
return (1.0 - depth * zBufferParameters.y) / (depth * zBufferParameters.x);
}
// Taken from:
// https://www.cyanilux.com/tutorials/depth/#depth-output
float EyeDepthToNonLinear(float depth, float4 zBufferParameters)
{
return (1.0 - depth * zBufferParameters.w) / (depth * zBufferParameters.z);
}
// Same as LinearEyeDepth except supports orthographic projection. Use projection keywords to restrict support to either
// of these modes as an optimisation.
float CrestLinearEyeDepth(const float i_rawDepth)
{
#if !defined(_PROJECTION_ORTHOGRAPHIC)
// Handles UNITY_REVERSED_Z for us.
#if defined(UNITY_CG_INCLUDED)
float perspective = LinearEyeDepth(i_rawDepth);
#elif defined(UNITY_COMMON_INCLUDED)
float perspective = LinearEyeDepth(i_rawDepth, _ZBufferParams);
#endif
#endif // _PROJECTION
#if !defined(_PROJECTION_PERSPECTIVE)
// Orthographic Depth taken and modified from:
// https://github.com/keijiro/DepthInverseProjection/blob/master/Assets/InverseProjection/Resources/InverseProjection.shader
float near = _ProjectionParams.y;
float far = _ProjectionParams.z;
float isOrthographic = unity_OrthoParams.w;
#if defined(UNITY_REVERSED_Z)
float orthographic = lerp(far, near, i_rawDepth);
#else
float orthographic = lerp(near, far, i_rawDepth);
#endif // UNITY_REVERSED_Z
#endif // _PROJECTION
#if defined(_PROJECTION_ORTHOGRAPHIC)
return orthographic;
#elif defined(_PROJECTION_PERSPECTIVE)
return perspective;
#else
// If a shader does not have the projection enumeration, then assume they want to support both projection modes.
return lerp(perspective, orthographic, isOrthographic);
#endif // _PROJECTION
}
m_UtilityNameSpaceEnd
#endif // d_WaveHarmonic_Utility_Depth

View File

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

View File

@@ -0,0 +1,71 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#ifndef d_WaveHarmonic_Utility_Filtering
#define d_WaveHarmonic_Utility_Filtering
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Macros.hlsl"
m_UtilityNameSpace
// Taken from:
// https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1
//
// The following code is licensed under the MIT license:
// https://gist.github.com/TheRealMJP/bc503b0b87b643d3505d41eab8b332ae
//
// Samples a texture with Catmull-Rom filtering, using 9 texture fetches instead of 16.
// See http://vec3.ca/bicubic-filtering-in-fewer-taps/ for more details
float4 SampleTextureCatmullRom(in Texture2D<float4> tex, in SamplerState linearSampler, in float2 uv, in float2 texSize)
{
// We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
// down the sample location to get the exact center of our "starting" texel. The starting texel will be at
// location [1, 1] in the grid, where [0, 0] is the top left corner.
float2 samplePos = uv * texSize;
float2 texPos1 = floor(samplePos - 0.5f) + 0.5f;
// Compute the fractional offset from our starting texel to our original sample location, which we'll
// feed into the Catmull-Rom spline function to get our filter weights.
float2 f = samplePos - texPos1;
// Compute the Catmull-Rom weights using the fractional offset that we calculated earlier.
// These equations are pre-expanded based on our knowledge of where the texels will be located,
// which lets us avoid having to evaluate a piece-wise function.
float2 w0 = f * (-0.5f + f * (1.0f - 0.5f * f));
float2 w1 = 1.0f + f * f * (-2.5f + 1.5f * f);
float2 w2 = f * (0.5f + f * (2.0f - 1.5f * f));
float2 w3 = f * f * (-0.5f + 0.5f * f);
// Work out weighting factors and sampling offsets that will let us use bilinear filtering to
// simultaneously evaluate the middle 2 samples from the 4x4 grid.
float2 w12 = w1 + w2;
float2 offset12 = w2 / (w1 + w2);
// Compute the final UV coordinates we'll use for sampling the texture
float2 texPos0 = texPos1 - 1;
float2 texPos3 = texPos1 + 2;
float2 texPos12 = texPos1 + offset12;
texPos0 /= texSize;
texPos3 /= texSize;
texPos12 /= texSize;
float4 result = 0.0f;
result += tex.SampleLevel(linearSampler, float2(texPos0.x, texPos0.y), 0.0f) * w0.x * w0.y;
result += tex.SampleLevel(linearSampler, float2(texPos12.x, texPos0.y), 0.0f) * w12.x * w0.y;
result += tex.SampleLevel(linearSampler, float2(texPos3.x, texPos0.y), 0.0f) * w3.x * w0.y;
result += tex.SampleLevel(linearSampler, float2(texPos0.x, texPos12.y), 0.0f) * w0.x * w12.y;
result += tex.SampleLevel(linearSampler, float2(texPos12.x, texPos12.y), 0.0f) * w12.x * w12.y;
result += tex.SampleLevel(linearSampler, float2(texPos3.x, texPos12.y), 0.0f) * w3.x * w12.y;
result += tex.SampleLevel(linearSampler, float2(texPos0.x, texPos3.y), 0.0f) * w0.x * w3.y;
result += tex.SampleLevel(linearSampler, float2(texPos12.x, texPos3.y), 0.0f) * w12.x * w3.y;
result += tex.SampleLevel(linearSampler, float2(texPos3.x, texPos3.y), 0.0f) * w3.x * w3.y;
return result;
}
m_UtilityNameSpaceEnd
#endif // d_WaveHarmonic_Utility_Filtering

View File

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

View File

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

View File

@@ -0,0 +1,257 @@
// Crest Water System
// This file is subject to the Unity Companion License:
// https://github.com/Unity-Technologies/Graphics/blob/7ff8fd444c179fd9bb380d61f4865be6935b47dd/LICENSE.md
// Adds functions from SRP.
// Adapted from:
// https://github.com/Unity-Technologies/Graphics/blob/8f54e6591e93fb3bf8e9879a0e43665dfbe2f629/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl
#ifndef UNITY_COMMON_INCLUDED
#define UNITY_COMMON_INCLUDED
// Add "real" alias for "fixed". Helps with including files downstream.
#define real fixed
#define real2 fixed2
#define real3 fixed3
#define real4 fixed4
// Commented lines have no "fixed" equivalent.
#define real2x2 fixed2x2
// #define real2x3 fixed2x3
// #define real2x4 fixed2x4
// #define real3x2 fixed3x2
#define real3x3 fixed3x3
// #define real3x4 fixed3x4
// #define real4x3 fixed4x3
#define real4x4 fixed4x4
//
// MACROS
//
#define ZERO_INITIALIZE(type, name) UNITY_INITIALIZE_OUTPUT(type,name)
#define TransformObjectToHClip(positionOS) UnityObjectToClipPos(float4(positionOS, 1.0))
// Taken from:
// com.unity.render-pipelines.core@10.5.0/ShaderLibrary/API/D3D11.hlsl
// com.unity.render-pipelines.core@10.5.0/ShaderLibrary/API/Metal.hlsl
// com.unity.render-pipelines.core@10.5.0/ShaderLibrary/API/Switch.hlsl
// com.unity.render-pipelines.core@10.5.0/ShaderLibrary/API/Vulkan.hlsl
// GameCore, PSSL etc require an NDA so hard to confirm how some of these APIs are implemented, but the PPv2 package has
// some of APIs (the ones we use) and they are the same:
// com.unity.postprocessing/PostProcessing/Shaders/API/
// Texture abstraction.
#define TEXTURE2D(textureName) UNITY_DECLARE_TEX2D_NOSAMPLER(textureName)
#define TEXTURE2D_ARRAY(textureName) UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(textureName)
#define TEXTURECUBE(textureName) UNITY_DECLARE_TEXCUBE_NOSAMPLER(textureName)
// #define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
// #define TEXTURE3D(textureName) Texture3D textureName
// #ifdef SHADER_API_D3D11
// #define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)
// #define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)
// #define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)
// #define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)
// #define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)
// #define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)
// #define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)
// #define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)
// #define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)
// #define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)
// #else // !SHADER_API_D3D11
// #define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName
// #define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray_float textureName
// #define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName
// #define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray_float textureName
// #define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName
// #define TEXTURE2D_HALF(textureName) Texture2D_half textureName
// #define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray_half textureName
// #define TEXTURECUBE_HALF(textureName) TextureCube_half textureName
// #define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray_half textureName
// #define TEXTURE3D_HALF(textureName) Texture3D_half textureName
// #endif // SHADER_API_D3D11
// #define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
// #define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
// #define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
// #define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
// #define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
#define SAMPLER(samplerName) SamplerState samplerName
// #define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
// #define ASSIGN_SAMPLER(samplerName, samplerValue) samplerName = samplerValue
// #define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
// #define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
// #define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
// #define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
// #define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
// #define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
// #define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
// #define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
// #define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
// #define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
// #define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
// #define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
// #define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
// #define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
// #define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
// #define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
// #define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
// #define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
// We cannot use Unity's macros because they change the samplerName and it needs to be unchanged.
#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
// #define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
// #define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
// #define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
// #define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
// #define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
// #define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
// #define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
// #define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
// #define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
// #define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
// #define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
// #define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
// #define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
// #define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
// #define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)
// #define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
// #define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
#undef SAMPLE_DEPTH_TEXTURE
// #undef SAMPLE_DEPTH_TEXTURE_LOD
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
// #define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r
#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
// #define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
// #define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
// #ifndef SHADER_API_SWITCH
// #define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
// #endif
// #define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
// #define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
// #define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
// #define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
// #define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
// #define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
// #define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
// #define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
// #define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
// #define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
// #define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)
// Generates a triangle in homogeneous clip space, s.t.
// v0 = (-1, -1, 1), v1 = (3, -1, 1), v2 = (-1, 3, 1).
float2 GetFullScreenTriangleTexCoord(uint vertexID)
{
#if UNITY_UV_STARTS_AT_TOP
return float2((vertexID << 1) & 2, 1.0 - (vertexID & 2));
#else
return float2((vertexID << 1) & 2, vertexID & 2);
#endif
}
float4 GetFullScreenTriangleVertexPosition(uint vertexID, float z = UNITY_NEAR_CLIP_VALUE)
{
float2 uv = float2((vertexID << 1) & 2, vertexID & 2);
return float4(uv * 2.0 - 1.0, z, 1.0);
}
#endif // UNITY_COMMON_INCLUDED
//
// FUNCTIONS
//
// Keep the following unguarded
// Taken and modified from:
// com.unity.render-pipelines.core@12.0.0/ShaderLibrary/Common.hlsl
float4 CrestComputeClipSpacePosition(float2 positionNDC, float deviceDepth)
{
float4 positionCS = float4(positionNDC * 2.0 - 1.0, deviceDepth, 1.0);
// positionCS.y was flipped here but that is SRP specific to solve flip baked into matrix.
return positionCS;
}
// Taken and modified from:
// com.unity.render-pipelines.core@12.0.0/ShaderLibrary/Common.hlsl
float3 CrestComputeWorldSpacePosition(float2 positionNDC, float deviceDepth, float4x4 invViewProjMatrix)
{
float4 positionCS = CrestComputeClipSpacePosition(positionNDC, deviceDepth);
float4 hpositionWS = mul(invViewProjMatrix, positionCS);
return hpositionWS.xyz / hpositionWS.w;
}
// Taken from:
// com.unity.render-pipelines.core@12.0.0/ShaderLibrary/Common.hlsl
float3 CrestComputeWorldSpacePosition(float4 positionCS, float4x4 invViewProjMatrix)
{
float4 hpositionWS = mul(invViewProjMatrix, positionCS);
return hpositionWS.xyz / hpositionWS.w;
}
#undef ComputeClipSpacePosition
#undef ComputeWorldSpacePosition
// Replace these with our own as ComputeClipSpacePosition flips the Y which is not correct for BIRP.
#define ComputeClipSpacePosition CrestComputeClipSpacePosition
#define ComputeWorldSpacePosition CrestComputeWorldSpacePosition
// Taken from:
// com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl
real3 CrestUnpackNormalmapRGorAG(real4 packednormal)
{
// This do the trick
packednormal.x *= packednormal.w;
real3 normal;
normal.xy = packednormal.xy * 2 - 1;
normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));
return normal;
}
// Taken from:
// com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl
inline real3 CrestUnpackNormal(real4 packednormal)
{
#if defined(UNITY_NO_DXT5nm)
return packednormal.xyz * 2 - 1;
#elif defined(UNITY_ASTC_NORMALMAP_ENCODING)
return UnpackNormalDXT5nm(packednormal);
#else
return CrestUnpackNormalmapRGorAG(packednormal);
#endif
}
#undef UnpackNormal
// Replace these to solve Unity bug "ambiguous call to 'UnpackNormalmapRGorAG'"
#define UnpackNormal CrestUnpackNormal

View File

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

View File

@@ -0,0 +1,75 @@
// Crest Water System
// This file is subject to the Unity Companion License:
// https://github.com/Unity-Technologies/Graphics/blob/7ff8fd444c179fd9bb380d61f4865be6935b47dd/LICENSE.md
// Adds functions from SRP.
// Adapted from:
// https://github.com/Unity-Technologies/Graphics/blob/8f54e6591e93fb3bf8e9879a0e43665dfbe2f629/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Core.hlsl
// https://github.com/Unity-Technologies/Graphics/blob/7ff8fd444c179fd9bb380d61f4865be6935b47dd/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/TextureXR.hlsl
#ifndef BUILTIN_PIPELINE_CORE_INCLUDED
#define BUILTIN_PIPELINE_CORE_INCLUDED
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Common.hlsl"
// Stereo-related bits
#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
#define SLICE_ARRAY_INDEX unity_StereoEyeIndex
#define COORD_TEXTURE2D_X(pixelCoord) uint3(pixelCoord, SLICE_ARRAY_INDEX)
#define TEXTURE2D_X(textureName) TEXTURE2D_ARRAY(textureName)
// #define TEXTURE2D_X_PARAM(textureName, samplerName) TEXTURE2D_ARRAY_PARAM(textureName, samplerName)
// #define TEXTURE2D_X_ARGS(textureName, samplerName) TEXTURE2D_ARRAY_ARGS(textureName, samplerName)
// #define TEXTURE2D_X_HALF(textureName) TEXTURE2D_ARRAY_HALF(textureName)
// #define TEXTURE2D_X_FLOAT(textureName) TEXTURE2D_ARRAY_FLOAT(textureName)
#define RW_TEXTURE2D_X(type, textureName) RW_TEXTURE2D_ARRAY(type, textureName)
#define LOAD_TEXTURE2D_X(textureName, unCoord2) LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, SLICE_ARRAY_INDEX)
// #define LOAD_TEXTURE2D_X_LOD(textureName, unCoord2, lod) LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, SLICE_ARRAY_INDEX, lod)
#define SAMPLE_TEXTURE2D_X(textureName, samplerName, coord2) SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, SLICE_ARRAY_INDEX)
// #define SAMPLE_TEXTURE2D_X_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, SLICE_ARRAY_INDEX, lod)
// #define GATHER_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, SLICE_ARRAY_INDEX)
// #define GATHER_RED_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_RED_TEXTURE2D(textureName, samplerName, float3(coord2, SLICE_ARRAY_INDEX))
// #define GATHER_GREEN_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_GREEN_TEXTURE2D(textureName, samplerName, float3(coord2, SLICE_ARRAY_INDEX))
// #define GATHER_BLUE_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_BLUE_TEXTURE2D(textureName, samplerName, float3(coord2, SLICE_ARRAY_INDEX))
#else // UNITY_STEREO
#define SLICE_ARRAY_INDEX 0
#define COORD_TEXTURE2D_X(pixelCoord) pixelCoord
#define TEXTURE2D_X(textureName) TEXTURE2D(textureName)
// #define TEXTURE2D_X_PARAM(textureName, samplerName) TEXTURE2D_PARAM(textureName, samplerName)
// #define TEXTURE2D_X_ARGS(textureName, samplerName) TEXTURE2D_ARGS(textureName, samplerName)
// #define TEXTURE2D_X_HALF(textureName) TEXTURE2D_HALF(textureName)
// #define TEXTURE2D_X_FLOAT(textureName) TEXTURE2D_FLOAT(textureName)
#define RW_TEXTURE2D_X RW_TEXTURE2D
#define LOAD_TEXTURE2D_X(textureName, unCoord2) LOAD_TEXTURE2D(textureName, unCoord2)
// #define LOAD_TEXTURE2D_X_LOD(textureName, unCoord2, lod) LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod)
#define SAMPLE_TEXTURE2D_X(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2)
// #define SAMPLE_TEXTURE2D_X_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)
// #define GATHER_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_TEXTURE2D(textureName, samplerName, coord2)
// #define GATHER_RED_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_RED_TEXTURE2D(textureName, samplerName, coord2)
// #define GATHER_GREEN_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2)
// #define GATHER_BLUE_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2)
#endif // UNITY_STEREO
// Helper macro to assign view index during compute/ray pass (usually from SV_DispatchThreadID or DispatchRaysIndex())
#if defined(SHADER_STAGE_COMPUTE) || defined(SHADER_STAGE_RAY_TRACING)
#if defined(UNITY_STEREO_INSTANCING_ENABLED)
#define UNITY_XR_ASSIGN_VIEW_INDEX(viewIndex) unity_StereoEyeIndex = viewIndex;
#else
#define UNITY_XR_ASSIGN_VIEW_INDEX(viewIndex)
#endif
#endif
#endif // BUILTIN_PIPELINE_CORE_INCLUDED

View File

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

View File

@@ -0,0 +1,18 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// Defines missing inputs.
float4x4 _Crest_InverseViewProjection;
float4x4 _Crest_InverseViewProjectionRight;
#undef UNITY_MATRIX_I_VP
#if defined(STEREO_INSTANCING_ON) || defined(STEREO_MULTIVIEW_ON)
#define UNITY_MATRIX_I_VP (unity_StereoEyeIndex == 0 ? _Crest_InverseViewProjection : _Crest_InverseViewProjectionRight)
#else
#define UNITY_MATRIX_I_VP _Crest_InverseViewProjection
#endif
// Not set and _ScreenParams.zw is "1.0 + 1.0 / _ScreenParams.xy"
#define _ScreenSize float4(_ScreenParams.xy, float2(1.0, 1.0) / _ScreenParams.xy)

View File

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

View File

@@ -0,0 +1,125 @@
// Crest Water System
// Copyright (c) 2016 Unity Technologies
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// Screen-space shadow helpers.
// Taken and adapted from:
// 2020.3.12f1/DefaultResourcesExtra/Internal-ScreenSpaceShadows.shader
// Main changes is that now only world position is required. Specialised for the shadow LOD data.
// Add multi_compile_shadowcollector pragma to get SHADOWS_SPLIT_SPHERES and SHADOWS_SINGLE_CASCADE.
// https://docs.unity3d.com/Manual/SL-MultipleProgramVariants.html
// SHADOWS_SCREEN + SHADOWS_CUBE will never be triggered for transparency, but
// Unity still compiles the variant which causes compiler errors.
#if defined(_SURFACE_TYPE_TRANSPARENT) && !defined(SHADERGRAPH_PREVIEW) && !defined(SHADOWS_SCREEN) && !defined(SHADOWS_CUBE)
#define d_Crest_ReceiveShadowsTransparent 1
#endif
#if d_Crest_ReceiveShadowsTransparent
#include "UnityShadowLibrary.cginc"
#ifndef SHADOWMAPSAMPLER_DEFINED
UNITY_DECLARE_SHADOWMAP(_ShadowMapTexture);
#define SHADOWMAPSAMPLER_DEFINED
#ifndef SHADOWMAPSAMPLER_AND_TEXELSIZE_DEFINED
float4 _ShadowMapTexture_TexelSize;
#define SHADOWMAPSAMPLER_AND_TEXELSIZE_DEFINED
#endif
#endif
//
// Keywords based defines
//
#if defined (SHADOWS_SPLIT_SPHERES)
#define GET_CASCADE_WEIGHTS(wpos) getCascadeWeights_splitSpheres(wpos)
#else
#define GET_CASCADE_WEIGHTS(wpos) getCascadeWeights(wpos)
#endif
#if defined (SHADOWS_SINGLE_CASCADE)
#define GET_SHADOW_COORDINATES(wpos) getShadowCoord_SingleCascade(wpos)
#else
#define GET_SHADOW_COORDINATES(wpos) getShadowCoord(wpos)
#endif
/**
* Gets the cascade weights based on the world position of the fragment.
* Returns a float4 with only one component set that corresponds to the appropriate cascade.
*/
inline fixed4 getCascadeWeights(float3 wpos)
{
// Calculate depth. Normally this would be depth from the depth buffer.
float z = dot(wpos - _WorldSpaceCameraPos.xyz, unity_CameraToWorld._m02_m12_m22);
fixed4 zNear = float4( z >= _LightSplitsNear );
fixed4 zFar = float4( z < _LightSplitsFar );
fixed4 weights = zNear * zFar;
return weights;
}
/**
* Gets the cascade weights based on the world position of the fragment and the poisitions of the split spheres for each cascade.
* Returns a float4 with only one component set that corresponds to the appropriate cascade.
*/
inline fixed4 getCascadeWeights_splitSpheres(float3 wpos)
{
float3 fromCenter0 = wpos.xyz - unity_ShadowSplitSpheres[0].xyz;
float3 fromCenter1 = wpos.xyz - unity_ShadowSplitSpheres[1].xyz;
float3 fromCenter2 = wpos.xyz - unity_ShadowSplitSpheres[2].xyz;
float3 fromCenter3 = wpos.xyz - unity_ShadowSplitSpheres[3].xyz;
float4 distances2 = float4(dot(fromCenter0,fromCenter0), dot(fromCenter1,fromCenter1), dot(fromCenter2,fromCenter2), dot(fromCenter3,fromCenter3));
fixed4 weights = float4(distances2 < unity_ShadowSplitSqRadii);
weights.yzw = saturate(weights.yzw - weights.xyz);
return weights;
}
/**
* Returns the shadowmap coordinates for the given fragment based on the world position and z-depth.
* These coordinates belong to the shadowmap atlas that contains the maps for all cascades.
*/
inline float4 getShadowCoord(float4 wpos)
{
fixed4 cascadeWeights = GET_CASCADE_WEIGHTS(wpos.xyz);
float3 sc0 = mul (unity_WorldToShadow[0], wpos).xyz;
float3 sc1 = mul (unity_WorldToShadow[1], wpos).xyz;
float3 sc2 = mul (unity_WorldToShadow[2], wpos).xyz;
float3 sc3 = mul (unity_WorldToShadow[3], wpos).xyz;
float4 shadowMapCoordinate = float4(sc0 * cascadeWeights[0] + sc1 * cascadeWeights[1] + sc2 * cascadeWeights[2] + sc3 * cascadeWeights[3], 1);
#if defined(UNITY_REVERSED_Z)
float noCascadeWeights = 1 - dot(cascadeWeights, float4(1, 1, 1, 1));
shadowMapCoordinate.z += noCascadeWeights;
#endif
return shadowMapCoordinate;
}
/**
* Same as the getShadowCoord; but optimized for single cascade
*/
inline float4 getShadowCoord_SingleCascade( float4 wpos )
{
return float4(mul(unity_WorldToShadow[0], wpos).xyz, 0);
}
#endif // d_Crest_ReceiveShadowsTransparent

View File

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

View File

@@ -0,0 +1,200 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// Based on tutorial: https://connect.unity.com/p/adding-your-own-hlsl-code-to-shader-graph-the-custom-function-node
#ifndef CREST_LIGHTING_H
#define CREST_LIGHTING_H
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Globals.hlsl"
TEXTURE2D_X(_Crest_ScreenSpaceShadowTexture);
float4 _Crest_ScreenSpaceShadowTexture_TexelSize;
#if CREST_URP
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
// Unity renamed keyword.
#ifdef USE_FORWARD_PLUS
#define USE_CLUSTER_LIGHT_LOOP USE_FORWARD_PLUS
#endif
#endif // CREST_URP
#if CREST_HDRP
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#ifndef SHADERGRAPH_PREVIEW
#if CREST_HDRP_FORWARD_PASS
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl"
#endif
#endif
#if UNITY_VERSION < 202310
#define GetMeshRenderingLayerMask GetMeshRenderingLightLayer
#endif
#if UNITY_VERSION < 60000000
#if PROBE_VOLUMES_L1
#define AMBIENT_PROBE_BUFFER 1
#endif
#endif // CREST_HDRP
m_CrestNameSpace
// TODO: Move
void ApplyIndirectLightingMultiplier
(
inout half3 io_AmbientLight
)
{
// Allows control of baked lighting through volume framework.
#ifndef SHADERGRAPH_PREVIEW
// We could create a BuiltinData struct which would have rendering layers on it, but it seems more complicated.
io_AmbientLight *= GetIndirectDiffuseMultiplier(GetMeshRenderingLayerMask());
#endif
}
#else // CREST_HDRP
m_CrestNameSpace
#endif
void PrimaryLight
(
const float3 i_PositionWS,
out half3 o_Color,
out half3 o_Direction
)
{
#if CREST_HDRP
// We could get the main light the same way we get the main light shadows,
// but most of the data would be missing (including below horizon
// attenuation) which would require re-running the light loop which is expensive.
o_Direction = g_Crest_PrimaryLightDirection;
o_Color = g_Crest_PrimaryLightIntensity;
#elif CREST_URP
// Actual light data from the pipeline.
Light light = GetMainLight();
o_Direction = light.direction;
o_Color = light.color;
#elif CREST_BIRP
#ifndef USING_DIRECTIONAL_LIGHT
// Yes. This function wants the world position of the surface.
o_Direction = normalize(UnityWorldSpaceLightDir(i_PositionWS));
#else
o_Direction = _WorldSpaceLightPos0.xyz;
#endif
o_Color = _LightColor0.rgb;
#endif
}
void AmbientLight(out half3 o_AmbientLight)
{
// Use the constant term (0th order) of SH stuff - this is the average.
o_AmbientLight =
#if AMBIENT_PROBE_BUFFER
half3(_AmbientProbeData[0].w, _AmbientProbeData[1].w, _AmbientProbeData[2].w);
#else
half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
#endif
#if CREST_HDRP
ApplyIndirectLightingMultiplier(o_AmbientLight);
#endif
}
// Position: SRP = WS / BIRP = SS (z ignored)
half PrimaryLightShadows(const float3 i_Position)
{
// Unshadowed.
half shadow = 1;
#if CREST_URP
// We could skip GetMainLight but this is recommended approach which is likely more robust to API changes.
float4 shadowCoord = TransformWorldToShadowCoord(i_Position);
Light light = GetMainLight(TransformWorldToShadowCoord(i_Position));
shadow = light.shadowAttenuation;
#endif
#ifndef SHADERGRAPH_PREVIEW
#if CREST_HDRP_FORWARD_PASS
DirectionalLightData light = _DirectionalLightDatas[_DirectionalShadowIndex];
HDShadowContext context = InitShadowContext();
context.directionalShadowData = _HDDirectionalShadowData[_DirectionalShadowIndex];
float3 positionWS = GetCameraRelativePositionWS(i_Position);
// From Unity:
// > With XR single-pass and camera-relative: offset position to do lighting computations from the combined center view (original camera matrix).
// > This is required because there is only one list of lights generated on the CPU. Shadows are also generated once and shared between the instanced views.
ApplyCameraRelativeXR(positionWS);
// TODO: Pass in screen space position and scene normal.
shadow = GetDirectionalShadowAttenuation
(
context,
0, // positionSS
positionWS,
0, // normalWS
light.shadowIndex,
-light.forward
);
// Apply shadow strength from main light.
shadow = LerpWhiteTo(shadow, light.shadowDimmer);
#endif // CREST_HDRP_FORWARD_PASS
#endif // SHADERGRAPH_PREVIEW
#if CREST_BIRP
shadow = LOAD_TEXTURE2D_X(_Crest_ScreenSpaceShadowTexture, min(i_Position.xy, _Crest_ScreenSpaceShadowTexture_TexelSize.zw - 1.0)).r;
#endif
return shadow;
}
half3 AdditionalLighting(const float3 i_PositionWS, const float4 i_ScreenPosition, const float2 i_StaticLightMapUV)
{
half3 color = 0.0;
#if CREST_URP
#if defined(_ADDITIONAL_LIGHTS)
// Shadowmask.
#if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
half4 shadowMask = SAMPLE_SHADOWMASK(i_StaticLightMapUV);
#elif !defined(LIGHTMAP_ON)
half4 shadowMask = unity_ProbesOcclusion;
#else
half4 shadowMask = half4(1, 1, 1, 1);
#endif
uint pixelLightCount = GetAdditionalLightsCount();
#ifdef _LIGHT_LAYERS
uint meshRenderingLayers = GetMeshRenderingLayer();
#endif
#if USE_CLUSTER_LIGHT_LOOP
InputData inputData = (InputData)0;
// For Foward+ LIGHT_LOOP_BEGIN macro uses inputData.normalizedScreenSpaceUV and inputData.positionWS.
inputData.normalizedScreenSpaceUV = i_ScreenPosition.xy / i_ScreenPosition.w;
inputData.positionWS = i_PositionWS;
#endif
LIGHT_LOOP_BEGIN(pixelLightCount)
// Includes shadows and cookies.
Light light = GetAdditionalLight(lightIndex, i_PositionWS, shadowMask);
#ifdef _LIGHT_LAYERS
if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
{
color += light.color * (light.distanceAttenuation * light.shadowAttenuation);
}
LIGHT_LOOP_END
#endif // _ADDITIONAL_LIGHTS
#endif // CREST_URP
return color;
}
m_CrestNameSpaceEnd
#endif

View File

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

View File

@@ -0,0 +1,50 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
#ifndef d_WaveHarmonic_Utility_Macros
#define d_WaveHarmonic_Utility_Macros
#define m_UtilityNameSpace namespace WaveHarmonic { namespace Utility {
#define m_UtilityNameSpaceEnd } }
#define m_Utility WaveHarmonic::Utility
#define m_UtilityVertex \
m_Utility::Varyings Vertex(m_Utility::Attributes i_Input) \
{ \
return m_Utility::Vertex(i_Input); \
}
#define m_UtilityFragment(type) \
type Fragment(m_Utility::Varyings i_Input) : SV_Target \
{ \
return m_Utility::Fragment(i_Input); \
}
#define m_UtilityKernel(name) \
void Crest##name(uint3 id : SV_DispatchThreadID) \
{ \
m_Utility::name(id); \
}
#define m_UtilityKernelVariant(name, variant) \
void Crest##name##variant(uint3 id : SV_DispatchThreadID) \
{ \
m_Utility::name(id); \
}
#define m_UtilityKernelDefault(name) \
[numthreads(8, 8, 1)] \
void Crest##name(uint3 id : SV_DispatchThreadID) \
{ \
m_Utility::name(id); \
}
#define m_UtilityKernelDefaultVariant(name, variant) \
[numthreads(8, 8, 1)] \
void Crest##name##variant(uint3 id : SV_DispatchThreadID) \
{ \
m_Utility::name(id); \
}
#endif // d_WaveHarmonic_Utility_Macros

View File

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

View File

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

View File

@@ -0,0 +1,35 @@
// See header/license in SOURCE.txt file accompanying this shader.
// Trivial modifications made to the code to translate it to HLSL by Huw Bowles
#ifndef CREST_GPU_NOISE_INCLUDED
#define CREST_GPU_NOISE_INCLUDED
uint baseHash(uint3 p)
{
p = 1103515245U * ((p.xyz >> 1U) ^ (p.yzx));
uint h32 = 1103515245U * ((p.x^p.z) ^ (p.y >> 3U));
return h32 ^ (h32 >> 16);
}
float hash13(uint3 x)
{
uint n = baseHash(x);
return float(n)*(1.0 / float(0xffffffffU));
}
float2 hash23(float3 x)
{
uint n = baseHash(x);
uint2 rz = uint2(n, n * 48271U); //see: http://random.mat.sbg.ac.at/results/karl/server/node4.html
return float2(rz.xy & (uint2)0x7fffffffU) / float(0x7fffffff);
}
float3 hash33(uint3 x)
{
uint n = baseHash(x);
uint3 rz = uint3(n, n * 16807U, n * 48271U); //see: http://random.mat.sbg.ac.at/results/karl/server/node4.html
return float3(rz & (uint3)0x7fffffffU) / float(0x7fffffff);
}
#endif // CREST_GPU_NOISE_INCLUDED

View File

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

View File

@@ -0,0 +1,10 @@
Source: https://www.shadertoy.com/view/Xt3cDn
Modifications: Trivial modifications made to the code to translate it to HLSL.
Copyright Notice:
Quality hashes collection
by nimitz 2018 (twitter: @stormoid)
The MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

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