'push'
This commit is contained in:
@@ -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 + 1) < _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 + 1) < _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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a2766c94869154bff829f45f26f23f7b
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,69 @@
|
||||
// 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_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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9553b06787bdd4dfb99d0563f6027d3f
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed3b576b7fe3c45b89366844bacbe976
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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;
|
||||
|
||||
SamplerState _Crest_linear_clamp_sampler;
|
||||
|
||||
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;
|
||||
bool g_Crest_PrimaryLightHasCookie;
|
||||
|
||||
float g_Crest_DynamicSoftShadowsFactor;
|
||||
|
||||
bool g_Crest_SampleAbsorptionSimulation;
|
||||
bool g_Crest_SampleScatteringSimulation;
|
||||
|
||||
// Motion Vector Parameters
|
||||
float g_Crest_WaterScaleChange;
|
||||
float2 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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 219ccb266236f4738917065843609901
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,133 @@
|
||||
// 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)
|
||||
{
|
||||
bool underwater = false;
|
||||
|
||||
// We are well below water.
|
||||
if (i_ForceUnderwater == 1)
|
||||
{
|
||||
underwater = true;
|
||||
}
|
||||
// We are well above water.
|
||||
else if (i_ForceUnderwater == 2)
|
||||
{
|
||||
underwater = false;
|
||||
}
|
||||
// Use facing.
|
||||
else
|
||||
{
|
||||
underwater = !i_FrontFace;
|
||||
}
|
||||
|
||||
return underwater;
|
||||
}
|
||||
|
||||
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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dd9b4a212760411496bde4d1b7a6b7c
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,69 @@
|
||||
// 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"
|
||||
|
||||
// NOTE: Unity does not recognize uint in FrameDebugger. It will be under Floats
|
||||
// with incorrect values. Change to int for debugging.
|
||||
uint _Crest_LodIndex;
|
||||
|
||||
|
||||
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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6fd0850e77df417eaf4485a17669d04
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,84 @@
|
||||
// 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_CrestFragmentVariant(type, name) \
|
||||
type Fragment(m_Crest::Varyings i_Input) : SV_Target \
|
||||
{ \
|
||||
return m_Crest::name(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)); \
|
||||
}
|
||||
|
||||
// Cross render pipeline kernels.
|
||||
#define m_CrestKernelXRP(name) \
|
||||
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void Crest##name##BRP(uint3 id : SV_DispatchThreadID) { m_Crest::name(id); } \
|
||||
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void Crest##name##HRP(uint3 id : SV_DispatchThreadID) { m_Crest::name(id); } \
|
||||
[numthreads(THREAD_GROUP_SIZE_X, THREAD_GROUP_SIZE_Y, 1)] void Crest##name##URP(uint3 id : SV_DispatchThreadID) { m_Crest::name(id); } \
|
||||
|
||||
#endif // CREST_MACROS_H
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: caa2db9eeee624124b0731445b09e163
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// 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_PACKAGE_HDRP (0)
|
||||
#define CREST_PACKAGE_URP (1)
|
||||
#define CREST_PORTALS (0)
|
||||
#define CREST_SHIFTING_ORIGIN (0)
|
||||
#define CREST_FULL_PRECISION_DISPLACEMENT (1)
|
||||
#define CREST_DISCARD_ATMOSPHERIC_SCATTERING (1)
|
||||
#define CREST_LEGACY_UNDERWATER (0)
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38f675942a9ca46a58afd1191b304f11
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fc5f278802cd484a8ee3e944ec8f858
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 298ae417217804dd48e3925a84f28b28
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 941ad013a0cbf4dec8d525ee790f5c6e
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65a9a0cfb233a4a418d51cbf55265c55
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#ifndef d_WaveHarmonic_Utility_Helpers
|
||||
#define d_WaveHarmonic_Utility_Helpers
|
||||
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Macros.hlsl"
|
||||
|
||||
m_UtilityNameSpace
|
||||
|
||||
void Swap(inout float a, inout float b)
|
||||
{
|
||||
float t = a; a = b; b = t;
|
||||
}
|
||||
|
||||
// Adapted from:
|
||||
// https://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf
|
||||
float3 ScreenSpaceDither(const float2 i_ScreenPosition)
|
||||
{
|
||||
// Iestyn's RGB dither (7 asm instructions) from Portal 2 X360, slightly modified for VR.
|
||||
float3 dither = dot(float2(171.0, 231.0), i_ScreenPosition.xy);
|
||||
dither.rgb = frac(dither.rgb / float3(103.0, 71.0, 97.0)) - float3(0.5, 0.5, 0.5);
|
||||
return (dither.rgb / 255.0);
|
||||
}
|
||||
|
||||
float2 WorldNormalToScreenDirection(const float3 i_PositionWS, const float3 i_NormalWS, const float4x4 i_MatrixVP, const float i_Offset)
|
||||
{
|
||||
const float3 p0 = i_PositionWS;
|
||||
const float3 p1 = p0 + i_NormalWS * i_Offset;
|
||||
|
||||
const float4 clip0 = mul(i_MatrixVP, float4(p0, 1));
|
||||
const float4 clip1 = mul(i_MatrixVP, float4(p1, 1));
|
||||
|
||||
const float2 uv0 = (clip0.xy / clip0.w) * 0.5 + 0.5;
|
||||
const float2 uv1 = (clip1.xy / clip1.w) * 0.5 + 0.5;
|
||||
|
||||
float2 direction = normalize(uv1 - uv0);
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
direction.y = -direction.y;
|
||||
#endif
|
||||
|
||||
return direction;
|
||||
}
|
||||
|
||||
m_UtilityNameSpaceEnd
|
||||
|
||||
#endif // d_WaveHarmonic_Utility_Helpers
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90443daddb561477ca109fbfe1d80fdd
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31c666ce642464bd1901041e360703ef
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,4 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// Empty.
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ff429977add540198b8820ff8f0cd7a
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,35 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// Builds on Unity's shim for Shader Graph.
|
||||
|
||||
#define BUILTIN_TARGET_API 1
|
||||
|
||||
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Includes/ShaderPass.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Defines.hlsl"
|
||||
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/Shims.hlsl"
|
||||
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/InputsDriven.hlsl"
|
||||
|
||||
#ifndef d_WaveHarmonic_Utility_LegacyCore
|
||||
#define d_WaveHarmonic_Utility_LegacyCore
|
||||
|
||||
|
||||
//
|
||||
// Inputs
|
||||
//
|
||||
|
||||
#undef UNITY_MATRIX_I_VP
|
||||
|
||||
#if defined(STEREO_INSTANCING_ON) || defined(STEREO_MULTIVIEW_ON)
|
||||
float4x4 _Crest_StereoInverseViewProjection[2];
|
||||
#define UNITY_MATRIX_I_VP _Crest_StereoInverseViewProjection[unity_StereoEyeIndex]
|
||||
#else
|
||||
float4x4 _Crest_InverseViewProjection;
|
||||
#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)
|
||||
|
||||
#endif // d_WaveHarmonic_Utility_LegacyCore
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8501e8dffc440417cb78449e6079d3fa
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,111 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#ifndef d_WaveHarmonic_Utility_ShaderGraphDefines
|
||||
#define d_WaveHarmonic_Utility_ShaderGraphDefines
|
||||
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
|
||||
#ifdef _BUILTIN_SPECULAR_SETUP
|
||||
#define _SPECULAR_SETUP _BUILTIN_SPECULAR_SETUP
|
||||
#endif
|
||||
|
||||
#ifdef _BUILTIN_TRANSPARENT_RECEIVES_SHADOWS
|
||||
#define _TRANSPARENT_RECEIVES_SHADOWS _BUILTIN_TRANSPARENT_RECEIVES_SHADOWS
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Passes
|
||||
//
|
||||
|
||||
#define SHADERPASS_FORWARD_ADD (20)
|
||||
#define SHADERPASS_DEFERRED (21)
|
||||
#define SHADERPASS_MOTION_VECTORS (22)
|
||||
|
||||
|
||||
//
|
||||
// Deferred Fix
|
||||
//
|
||||
|
||||
#if (defined(SHADER_API_GLES3) && !defined(SHADER_API_DESKTOP)) || defined(SHADER_API_GLES) || defined(SHADER_API_N3DS)
|
||||
#define UNITY_ALLOWED_MRT_COUNT 4
|
||||
#else
|
||||
#define UNITY_ALLOWED_MRT_COUNT 8
|
||||
#endif
|
||||
|
||||
// Required on Windows (and possibly others) to prevent tiling.
|
||||
#undef UNITY_SAMPLE_FULL_SH_PER_PIXEL
|
||||
#define UNITY_SAMPLE_FULL_SH_PER_PIXEL 1
|
||||
|
||||
|
||||
//
|
||||
// Stereo Instancing Fix
|
||||
//
|
||||
|
||||
#if defined(STEREO_INSTANCING_ON) && (defined(SHADER_API_D3D11) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE) || defined(SHADER_API_PSSL) || defined(SHADER_API_VULKAN) || (defined(SHADER_API_METAL) && !defined(UNITY_COMPILER_DXC)))
|
||||
#define UNITY_STEREO_INSTANCING_ENABLED
|
||||
#endif
|
||||
|
||||
#if defined(STEREO_MULTIVIEW_ON) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE) || defined(SHADER_API_VULKAN)) && !(defined(SHADER_API_SWITCH))
|
||||
#define UNITY_STEREO_MULTIVIEW_ENABLED
|
||||
#endif
|
||||
|
||||
// Redeclared their includes to insert shadow declarations at the right spot.
|
||||
// Adapted from:
|
||||
// Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/Shims.hlsl
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
||||
|
||||
// Duplicate define in Macros.hlsl
|
||||
#if defined (TRANSFORM_TEX)
|
||||
#undef TRANSFORM_TEX
|
||||
#endif
|
||||
|
||||
#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
|
||||
#undef GLOBAL_CBUFFER_START
|
||||
#if defined(UNITY_STEREO_MULTIVIEW_ENABLED) || ((defined(UNITY_SINGLE_PASS_STEREO) || defined(UNITY_STEREO_INSTANCING_ENABLED)) && (defined(SHADER_API_GLCORE) || defined(SHADER_API_GLES3) || defined(SHADER_API_METAL)))
|
||||
#define GLOBAL_CBUFFER_START(name) cbuffer name {
|
||||
#define GLOBAL_CBUFFER_END }
|
||||
#else
|
||||
#define GLOBAL_CBUFFER_START(name) CBUFFER_START(name)
|
||||
#define GLOBAL_CBUFFER_END CBUFFER_END
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/HLSLSupportShim.hlsl"
|
||||
|
||||
// Fix wrong definitions.
|
||||
#undef UNITY_SAMPLE_TEX2DARRAY
|
||||
#define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)
|
||||
|
||||
|
||||
//
|
||||
// Transparent Objects Receives Shadows
|
||||
//
|
||||
|
||||
#if _SURFACE_TYPE_TRANSPARENT
|
||||
#if _TRANSPARENT_RECEIVES_SHADOWS
|
||||
#if SHADERPASS == SHADERPASS_FORWARD || SHADERPASS == SHADERPASS_FORWARD_ADD
|
||||
#if DIRECTIONAL || DIRECTIONAL_COOKIE
|
||||
#if !SHADOWS_SCREEN
|
||||
|
||||
StructuredBuffer<float4x4> _Crest_WorldToShadow;
|
||||
|
||||
// Declarations for shadow collector.
|
||||
UNITY_DECLARE_SHADOWMAP(_ShadowMapTexture);
|
||||
float4 _ShadowMapTexture_TexelSize;
|
||||
#define SHADOWMAPSAMPLER_DEFINED 1
|
||||
#define SHADOWMAPSAMPLER_AND_TEXELSIZE_DEFINED 1
|
||||
|
||||
#define d_Crest_ShadowsOverriden 1
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // d_WaveHarmonic_Utility_ShaderGraphDefines
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d26727ac31d94682896ffbfdc685804
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,4 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// Empty.
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e956ca85fd1846899d2a3b106267dcd
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,109 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#include "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Includes/LegacyBuilding.hlsl"
|
||||
|
||||
//
|
||||
// Transparent Objects Receives Shadows
|
||||
//
|
||||
|
||||
#if d_Crest_ShadowsOverriden
|
||||
|
||||
#define unity_WorldToShadow _Crest_WorldToShadow
|
||||
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Shadows.hlsl"
|
||||
|
||||
#if defined(SHADER_API_MOBILE)
|
||||
#define m_UnitySampleShadowmap_PCF UnitySampleShadowmap_PCF5x5
|
||||
#else
|
||||
#define m_UnitySampleShadowmap_PCF UnitySampleShadowmap_PCF7x7
|
||||
#endif
|
||||
|
||||
// Same as UnityComputeShadowFadeDistance, except it uses keywords.
|
||||
float ComputeShadowFadeDistance(float3 positionWS, float viewZ)
|
||||
{
|
||||
// Use keyword instead of unity_ShadowFadeCenterAndType.w, as we are already
|
||||
// dependent on keywords anyway.
|
||||
return
|
||||
#if SHADOWS_SPLIT_SPHERES
|
||||
distance(positionWS, unity_ShadowFadeCenterAndType.xyz);
|
||||
#else
|
||||
viewZ;
|
||||
#endif
|
||||
}
|
||||
|
||||
float GetShadows(float3 positionWS, float4 uvLightMap)
|
||||
{
|
||||
float viewZ = -UnityWorldToViewPos(positionWS).z;
|
||||
float4 weights = GET_CASCADE_WEIGHTS(positionWS, viewZ);
|
||||
float4 coordinates = GET_SHADOW_COORDINATES(float4(positionWS, 1.0), weights);
|
||||
#if SHADOWS_SOFT
|
||||
half shadow = m_UnitySampleShadowmap_PCF(coordinates, 0);
|
||||
#else
|
||||
half shadow = UNITY_SAMPLE_SHADOW(_ShadowMapTexture, coordinates);
|
||||
#endif
|
||||
shadow = lerp(_LightShadowData.r, 1.0, shadow);
|
||||
|
||||
// Shadow Mask + mixed sun + static
|
||||
#if LIGHTMAP_ON && SHADOWS_SHADOWMASK && LIGHTMAP_SHADOW_MIXING
|
||||
float fade = UnityComputeShadowFade(ComputeShadowFadeDistance(positionWS, viewZ));
|
||||
half mask = UnitySampleBakedOcclusion(uvLightMap.xy, positionWS);
|
||||
shadow = UnityMixRealtimeAndBakedShadows(shadow, mask, fade);
|
||||
#endif
|
||||
|
||||
return shadow;
|
||||
}
|
||||
|
||||
#ifdef DIRECTIONAL
|
||||
#undef UNITY_LIGHT_ATTENUATION
|
||||
#define UNITY_LIGHT_ATTENUATION(destName, input, worldPos) \
|
||||
fixed destName = GetShadows(worldPos, input.lmap);
|
||||
#endif
|
||||
|
||||
#ifdef DIRECTIONAL_COOKIE
|
||||
#undef UNITY_LIGHT_ATTENUATION
|
||||
#define UNITY_LIGHT_ATTENUATION(destName, input, worldPos) \
|
||||
DECLARE_LIGHT_COORD(input, worldPos); \
|
||||
fixed destName = tex2D(_LightTexture0, lightCoord).w * GetShadows(worldPos, input.lmap);
|
||||
#endif
|
||||
|
||||
#endif // d_Crest_ShadowsOverriden
|
||||
|
||||
|
||||
//
|
||||
// Specular
|
||||
//
|
||||
|
||||
#ifdef _SPECULAR_SETUP
|
||||
#define SurfaceOutputStandard SurfaceOutputStandardSpecular
|
||||
#define BuildStandardSurfaceOutput BuildStandardSpecularSurfaceOutput
|
||||
#define LightingStandard LightingStandardSpecular
|
||||
#define LightingStandard_GI LightingStandardSpecular_GI
|
||||
#define LightingStandard_Deferred LightingStandardSpecular_Deferred
|
||||
|
||||
#if SHADERPASS == SHADERPASS_FORWARD_ADD
|
||||
#undef LightingStandard
|
||||
#define LightingStandard(x, y, z) LightingStandardSpecular(x, y, z); c.rgb += o.Emission;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _SPECULAR_SETUP
|
||||
#if SHADERPASS == SHADERPASS_FORWARD_ADD
|
||||
#define LightingStandard(x, y, z) LightingStandard(x, y, z); c.rgb += o.Emission;
|
||||
#endif // SHADERPASS_FORWARD_ADD
|
||||
#endif // _SPECULAR_SETUP
|
||||
|
||||
SurfaceOutputStandardSpecular BuildStandardSpecularSurfaceOutput(SurfaceDescription surfaceDescription, InputData inputData)
|
||||
{
|
||||
SurfaceData surface = SurfaceDescriptionToSurfaceData(surfaceDescription);
|
||||
|
||||
SurfaceOutputStandardSpecular o = (SurfaceOutputStandardSpecular)0;
|
||||
o.Albedo = surface.albedo;
|
||||
o.Normal = inputData.normalWS;
|
||||
o.Specular = surface.specular;
|
||||
o.Smoothness = surface.smoothness;
|
||||
o.Occlusion = surface.occlusion;
|
||||
o.Emission = surface.emission;
|
||||
o.Alpha = surface.alpha;
|
||||
return o;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5eab24690c4a74ceca26a143da611306
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// TODO:
|
||||
// #if defined(USING_STEREO_MATRICES)
|
||||
// float4x4 _StereoNonJitteredVP[2];
|
||||
// float4x4 _StereoPreviousVP[2];
|
||||
// #else
|
||||
// float4x4 _NonJitteredVP;
|
||||
// float4x4 _PreviousVP;
|
||||
// #endif
|
||||
|
||||
float4x4 _PreviousM;
|
||||
float4x4 _PreviousVP;
|
||||
float4x4 _NonJitteredVP;
|
||||
|
||||
bool _HasLastPositionData;
|
||||
bool _ForceNoMotion;
|
||||
float _MotionVectorDepthBias;
|
||||
|
||||
#undef UNITY_PREV_MATRIX_M
|
||||
#define UNITY_PREV_MATRIX_M _PreviousM
|
||||
#define _PrevViewProjMatrix _PreviousVP
|
||||
#define _NonJitteredViewProjMatrix _NonJitteredVP
|
||||
|
||||
// X : Use last frame positions (right now skinned meshes are the only objects that use this
|
||||
// Y : Force No Motion
|
||||
// Z : Z bias value
|
||||
const static float4 unity_MotionVectorsParams = float4(_HasLastPositionData, !_ForceNoMotion, _MotionVectorDepthBias, 0);
|
||||
|
||||
// Unity will populate this, but could not see when in source.
|
||||
float4 _LastTime;
|
||||
|
||||
// We want to gather some internal data from the BuildVaryings call to
|
||||
// avoid rereading and recalculating these values again in the ShaderGraph motion vector pass
|
||||
struct MotionVectorPassOutput
|
||||
{
|
||||
float3 positionOS;
|
||||
float3 positionWS;
|
||||
};
|
||||
|
||||
SurfaceDescription BuildSurfaceDescription(Varyings varyings)
|
||||
{
|
||||
SurfaceDescriptionInputs surfaceDescriptionInputs = BuildSurfaceDescriptionInputs(varyings);
|
||||
SurfaceDescription surfaceDescription = SurfaceDescriptionFunction(surfaceDescriptionInputs);
|
||||
return surfaceDescription;
|
||||
}
|
||||
|
||||
// Very hacky, but works!
|
||||
#define BuildVaryings(content) BuildVaryings(content, inout MotionVectorPassOutput motionVectorOutput)
|
||||
#define TransformObjectToWorld(content) TransformObjectToWorld(content); motionVectorOutput.positionOS = input.positionOS; motionVectorOutput.positionWS = positionWS;
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1eacca53c60984c4a8cadb624777e644
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,159 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// Adapted from:
|
||||
// Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/MotionVectorPass.hlsl
|
||||
|
||||
// This file is subject to the Unity Companion License:
|
||||
// https://github.com/Unity-Technologies/Graphics/blob/61584ec20cf305929dae85cec7b94ff2ed3942f3/LICENSE.md
|
||||
|
||||
#ifndef SG_MOTION_VECTORS_PASS_INCLUDED
|
||||
#define SG_MOTION_VECTORS_PASS_INCLUDED
|
||||
|
||||
#undef BuildVaryings
|
||||
#undef TransformObjectToWorld
|
||||
|
||||
float2 CalcNdcMotionVectorFromCsPositions(float4 posCS, float4 prevPosCS)
|
||||
{
|
||||
// Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled
|
||||
bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;
|
||||
if (forceNoMotion)
|
||||
return float2(0.0, 0.0);
|
||||
|
||||
// Non-uniform raster needs to keep the posNDC values in float to avoid additional conversions
|
||||
// since uv remap functions use floats
|
||||
float2 posNDC = posCS.xy * rcp(posCS.w);
|
||||
float2 prevPosNDC = prevPosCS.xy * rcp(prevPosCS.w);
|
||||
|
||||
float2 velocity;
|
||||
{
|
||||
// Calculate forward velocity
|
||||
velocity = (posNDC.xy - prevPosNDC.xy);
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
velocity.y = -velocity.y;
|
||||
#endif
|
||||
|
||||
// Convert velocity from NDC space (-1..1) to UV 0..1 space
|
||||
// Note: It doesn't mean we don't have negative values, we store negative or positive offset in UV space.
|
||||
// Note: ((posNDC * 0.5 + 0.5) - (prevPosNDC * 0.5 + 0.5)) = (velocity * 0.5)
|
||||
velocity.xy *= 0.5;
|
||||
}
|
||||
|
||||
return velocity;
|
||||
}
|
||||
|
||||
struct MotionVectorPassAttributes
|
||||
{
|
||||
float3 previousPositionOS : TEXCOORD4; // Contains previous frame local vertex position (for skinned meshes)
|
||||
};
|
||||
|
||||
// Note: these will have z == 0.0f in the pixel shader to save on bandwidth
|
||||
struct MotionVectorPassVaryings
|
||||
{
|
||||
float4 positionCSNoJitter;
|
||||
float4 previousPositionCSNoJitter;
|
||||
};
|
||||
|
||||
struct PackedMotionVectorPassVaryings
|
||||
{
|
||||
float3 positionCSNoJitter : CLIP_POSITION_NO_JITTER;
|
||||
float3 previousPositionCSNoJitter : PREVIOUS_CLIP_POSITION_NO_JITTER;
|
||||
};
|
||||
|
||||
PackedMotionVectorPassVaryings PackMotionVectorVaryings(MotionVectorPassVaryings regularVaryings)
|
||||
{
|
||||
PackedMotionVectorPassVaryings packedVaryings;
|
||||
packedVaryings.positionCSNoJitter = regularVaryings.positionCSNoJitter.xyw;
|
||||
packedVaryings.previousPositionCSNoJitter = regularVaryings.previousPositionCSNoJitter.xyw;
|
||||
return packedVaryings;
|
||||
}
|
||||
|
||||
MotionVectorPassVaryings UnpackMotionVectorVaryings(PackedMotionVectorPassVaryings packedVaryings)
|
||||
{
|
||||
MotionVectorPassVaryings regularVaryings;
|
||||
regularVaryings.positionCSNoJitter = float4(packedVaryings.positionCSNoJitter.xy, 0, packedVaryings.positionCSNoJitter.z);
|
||||
regularVaryings.previousPositionCSNoJitter = float4(packedVaryings.previousPositionCSNoJitter.xy, 0, packedVaryings.previousPositionCSNoJitter.z);
|
||||
return regularVaryings;
|
||||
}
|
||||
|
||||
float3 GetLastFrameDeformedPosition(Attributes input, MotionVectorPassOutput currentFrameMvData, float3 previousPositionOS)
|
||||
{
|
||||
Attributes lastFrameInputAttributes = input;
|
||||
lastFrameInputAttributes.positionOS = previousPositionOS;
|
||||
|
||||
VertexDescriptionInputs lastFrameVertexDescriptionInputs = BuildVertexDescriptionInputs(lastFrameInputAttributes);
|
||||
#if defined(AUTOMATIC_TIME_BASED_MOTION_VECTORS) && defined(GRAPH_VERTEX_USES_TIME_PARAMETERS_INPUT)
|
||||
lastFrameVertexDescriptionInputs.TimeParameters = _LastTime.yxz;
|
||||
#endif
|
||||
|
||||
VertexDescription lastFrameVertexDescription = VertexDescriptionFunction(lastFrameVertexDescriptionInputs);
|
||||
previousPositionOS = lastFrameVertexDescription.Position.xyz;
|
||||
|
||||
return previousPositionOS;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
// Vertex
|
||||
void vert(
|
||||
Attributes input,
|
||||
MotionVectorPassAttributes passInput,
|
||||
out PackedMotionVectorPassVaryings packedMvOutput,
|
||||
out PackedVaryings packedOutput)
|
||||
{
|
||||
Varyings output = (Varyings)0;
|
||||
MotionVectorPassVaryings mvOutput = (MotionVectorPassVaryings)0;
|
||||
MotionVectorPassOutput currentFrameMvData = (MotionVectorPassOutput)0;
|
||||
output = BuildVaryings(input, currentFrameMvData);
|
||||
packedOutput = PackVaryings(output);
|
||||
|
||||
const bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;
|
||||
|
||||
if (!forceNoMotion)
|
||||
{
|
||||
const bool hasDeformation = unity_MotionVectorsParams.x == 1; // Mesh has skinned deformation
|
||||
float3 previousPositionOS = hasDeformation ? passInput.previousPositionOS : input.positionOS;
|
||||
|
||||
#if defined(AUTOMATIC_TIME_BASED_MOTION_VECTORS) && defined(GRAPH_VERTEX_USES_TIME_PARAMETERS_INPUT)
|
||||
const bool applyDeformation = true;
|
||||
#else
|
||||
const bool applyDeformation = hasDeformation;
|
||||
#endif
|
||||
|
||||
#if defined(FEATURES_GRAPH_VERTEX)
|
||||
if (applyDeformation)
|
||||
previousPositionOS = GetLastFrameDeformedPosition(input, currentFrameMvData, previousPositionOS);
|
||||
else
|
||||
previousPositionOS = currentFrameMvData.positionOS;
|
||||
|
||||
#if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT)
|
||||
previousPositionOS -= currentFrameMvData.motionVector;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
mvOutput.positionCSNoJitter = mul(_NonJitteredViewProjMatrix, float4(currentFrameMvData.positionWS, 1.0f));
|
||||
mvOutput.previousPositionCSNoJitter = mul(_PrevViewProjMatrix, mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1.0f)));
|
||||
}
|
||||
|
||||
packedMvOutput = PackMotionVectorVaryings(mvOutput);
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
// Fragment
|
||||
float4 frag(
|
||||
// Note: packedMvInput needs to be before packedInput as otherwise we get the following error in the speed tree 8 SG:
|
||||
// "Non system-generated input signature parameter () cannot appear after a system generated value"
|
||||
PackedMotionVectorPassVaryings packedMvInput,
|
||||
PackedVaryings packedInput) : SV_Target
|
||||
{
|
||||
Varyings input = UnpackVaryings(packedInput);
|
||||
MotionVectorPassVaryings mvInput = UnpackMotionVectorVaryings(packedMvInput);
|
||||
UNITY_SETUP_INSTANCE_ID(input);
|
||||
SurfaceDescription surfaceDescription = BuildSurfaceDescription(input);
|
||||
|
||||
#if defined(_ALPHATEST_ON)
|
||||
clip(surfaceDescription.Alpha - surfaceDescription.AlphaClipThreshold);
|
||||
#endif
|
||||
|
||||
return float4(CalcNdcMotionVectorFromCsPositions(mvInput.positionCSNoJitter, mvInput.previousPositionCSNoJitter), 0, 0);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae5323918c4b24b5c87c6f941810e225
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,105 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// 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.
|
||||
|
||||
// Taken from:
|
||||
// 2020.3.12f1/DefaultResourcesExtra/Internal-ScreenSpaceShadows.shader
|
||||
|
||||
#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, z) getCascadeWeights_splitSpheres(wpos)
|
||||
#else
|
||||
#define GET_CASCADE_WEIGHTS(wpos, z) getCascadeWeights( wpos, z )
|
||||
#endif
|
||||
|
||||
#if defined (SHADOWS_SINGLE_CASCADE)
|
||||
#define GET_SHADOW_COORDINATES(wpos,cascadeWeights) getShadowCoord_SingleCascade(wpos)
|
||||
#else
|
||||
#define GET_SHADOW_COORDINATES(wpos,cascadeWeights) getShadowCoord(wpos,cascadeWeights)
|
||||
#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, float z)
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14d63b54d73024767903a5caa23e8e53
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,153 @@
|
||||
// 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"
|
||||
|
||||
#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 // USE_FORWARD_PLUS
|
||||
#endif // CREST_URP
|
||||
|
||||
#if CREST_HDRP
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
||||
|
||||
#if UNITY_VERSION < 202310
|
||||
#define GetMeshRenderingLayerMask GetMeshRenderingLightLayer
|
||||
#endif // UNITY_VERSION
|
||||
|
||||
#if UNITY_VERSION < 60000000
|
||||
#if PROBE_VOLUMES_L1
|
||||
#define AMBIENT_PROBE_BUFFER 1
|
||||
#endif // PROBE_VOLUMES_L1
|
||||
#endif // UNITY_VERSION
|
||||
#endif // CREST_HDRP
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
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;
|
||||
// Prevents divide by zero.
|
||||
if (all(o_Direction == 0)) o_Direction = half3(0.0, 1.0, 0.0);
|
||||
#endif
|
||||
o_Color = _LightColor0.rgb;
|
||||
#if SHADERPASS == SHADERPASS_FORWARD_ADD
|
||||
#if !SHADOWS_SCREEN
|
||||
// FIXME: undeclared identifier 'IN' in Pass: BuiltIn ForwardAdd, Vertex program with DIRECTIONAL SHADOWS_SCREEN
|
||||
UNITY_LIGHT_ATTENUATION(attenuation, IN, i_PositionWS)
|
||||
o_Color *= attenuation;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
half3 AmbientLight(const half3 i_AmbientLight)
|
||||
{
|
||||
half3 ambient = i_AmbientLight;
|
||||
|
||||
#ifndef SHADERGRAPH_PREVIEW
|
||||
#if CREST_HDRP
|
||||
// Allows control of baked lighting through volume framework.
|
||||
// We could create a BuiltinData struct which would have rendering layers on it, but it seems more complicated.
|
||||
ambient *= GetIndirectDiffuseMultiplier(GetMeshRenderingLayerMask());
|
||||
#endif // CREST_HDRP
|
||||
#endif // SHADERGRAPH_PREVIEW
|
||||
|
||||
return ambient;
|
||||
}
|
||||
|
||||
half3 AmbientLight()
|
||||
{
|
||||
// Use the constant term (0th order) of SH stuff - this is the average.
|
||||
const half3 ambient =
|
||||
#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
|
||||
|
||||
return AmbientLight(ambient);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// HDRP todo.
|
||||
// BIRP has additional lights as additional passes. Handled elsewhere.
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 986eee3bc5a7a49f7a6a1f94c96d22e8
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac63edd7bcb3b4b35a5ea50c7deb4202
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85562641776fc423e829bb13477e80f3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f79fd5a427da4de09803ded352ecfb1
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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.
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ae623fc941b44349a1836e6ab666922
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 389b0f071dd5843c394f5255cd6ec73c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#ifndef d_WaveHarmonic_Utility_RenderPipeline_Compute
|
||||
#define d_WaveHarmonic_Utility_RenderPipeline_Compute
|
||||
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Settings.Crest.hlsl"
|
||||
|
||||
// Compute does not have an equivalent of PackageRequirements.
|
||||
// We must handle it ourselves.
|
||||
|
||||
// Fallback to BIRP if HDRP package missing.
|
||||
#if _HRP
|
||||
#if (CREST_PACKAGE_HDRP != 1)
|
||||
#undef _HRP
|
||||
#define _BRP 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Fallback to BIRP if URP package missing.
|
||||
#if _URP
|
||||
#if (CREST_PACKAGE_URP != 1)
|
||||
#undef _URP
|
||||
#define _BRP 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if _BRP
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Core.hlsl"
|
||||
#endif
|
||||
|
||||
#if _HRP
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
||||
#endif
|
||||
|
||||
#if _URP
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Stereo Rendering
|
||||
//
|
||||
|
||||
// Unity 6 only, but had compilation errors for non HDRP anyway:
|
||||
// #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl"
|
||||
|
||||
#ifndef RW_TEXTURE2D_X
|
||||
#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
|
||||
#define COORD_TEXTURE2D_X(pixelCoord) uint3(pixelCoord, SLICE_ARRAY_INDEX)
|
||||
#define RW_TEXTURE2D_X(type, textureName) RW_TEXTURE2D_ARRAY(type, textureName)
|
||||
#else // UNITY_STEREO
|
||||
#define COORD_TEXTURE2D_X(pixelCoord) pixelCoord
|
||||
#define RW_TEXTURE2D_X RW_TEXTURE2D
|
||||
#endif // UNITY_STEREO
|
||||
#endif // RW_TEXTURE2D_X
|
||||
|
||||
#ifndef UNITY_XR_ASSIGN_VIEW_INDEX
|
||||
// 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 // UNITY_XR_ASSIGN_VIEW_INDEX
|
||||
|
||||
#endif // d_WaveHarmonic_Utility_RenderPipeline_Compute
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68cb1a44e787e45bd9de666d527b10f2
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff5a7cc0943db46db9eac87f50e38097
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#ifndef d_WaveHarmonic_Utility_RenderPipeline_HDRP_Common
|
||||
#define d_WaveHarmonic_Utility_RenderPipeline_HDRP_Common
|
||||
|
||||
#define LoadSceneColor LoadCameraColor
|
||||
#define LoadSceneDepth LoadCameraDepth
|
||||
#define SampleSceneColor SampleCameraColor
|
||||
#define SampleSceneDepth SampleCameraDepth
|
||||
|
||||
#endif // d_WaveHarmonic_Utility_RenderPipeline_HDRP_Common
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 327c164f365e1468789c5950ac945e17
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,107 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#ifndef d_WaveHarmonic_Utility_RenderPipeline_Shadows
|
||||
#define d_WaveHarmonic_Utility_RenderPipeline_Shadows
|
||||
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Macros.hlsl"
|
||||
|
||||
#if _BRP
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Utility/Legacy/Shadows.hlsl"
|
||||
|
||||
bool _Crest_ClearShadows;
|
||||
#endif
|
||||
|
||||
#if _HRP
|
||||
// TODO: We might be able to expose this to give developers the option.
|
||||
// #pragma multi_compile SHADOW_ULTRA_LOW SHADOW_LOW SHADOW_MEDIUM SHADOW_HIGH
|
||||
|
||||
// Ultra low uses Gather to filter which should be same cost as not filtering. See algorithms per keyword:
|
||||
// Runtime/Lighting/Shadow/HDShadowAlgorithms.hlsl
|
||||
#define SHADOW_ULTRA_LOW
|
||||
#define AREA_SHADOW_LOW
|
||||
#define PUNCTUAL_SHADOW_ULTRA_LOW
|
||||
#define DIRECTIONAL_SHADOW_ULTRA_LOW
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl"
|
||||
#endif
|
||||
|
||||
#if _URP
|
||||
// Maybe this is the equivalent of the SHADOW_COLLECTOR_PASS define?
|
||||
// Inspired from com.unity.render-pipelines.universal/Shaders/Utils/ScreenSpaceShadows.shader
|
||||
#define _MAIN_LIGHT_SHADOWS_CASCADE
|
||||
#define MAIN_LIGHT_CALCULATE_SHADOWS
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
|
||||
#endif
|
||||
|
||||
m_UtilityNameSpace
|
||||
|
||||
#if _BRP
|
||||
half SampleShadows(const float4 i_positionWS)
|
||||
{
|
||||
// NOTE: "Shadow Projection > Close Fit" can still produce artefacts when away from caster, but this
|
||||
// appears to be an improvement over the compute shader.
|
||||
|
||||
// Calculate depth. Normally this would be depth from the depth buffer.
|
||||
float z = dot(i_positionWS.xyz - _WorldSpaceCameraPos.xyz, unity_CameraToWorld._m02_m12_m22);
|
||||
|
||||
float4 weights = GET_CASCADE_WEIGHTS(i_positionWS.xyz, z);
|
||||
float4 shadowCoord = GET_SHADOW_COORDINATES(i_positionWS, weights);
|
||||
half shadows = UNITY_SAMPLE_SHADOW(_ShadowMapTexture, shadowCoord);
|
||||
if (_Crest_ClearShadows) shadows = 1.0;
|
||||
shadows = lerp(_LightShadowData.r, 1.0, shadows);
|
||||
|
||||
return shadows;
|
||||
}
|
||||
|
||||
half ComputeShadowFade(const float4 i_positionWS)
|
||||
{
|
||||
float z = dot(i_positionWS.xyz - _WorldSpaceCameraPos.xyz, unity_CameraToWorld._m02_m12_m22);
|
||||
float fadeDistance = UnityComputeShadowFadeDistance(i_positionWS.xyz, z);
|
||||
float fade = UnityComputeShadowFade(fadeDistance);
|
||||
return fade;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if _HRP
|
||||
half SampleShadows(const float4 i_positionWS)
|
||||
{
|
||||
// Get directional light data. By definition we only have one directional light casting shadow.
|
||||
DirectionalLightData light = _DirectionalLightDatas[_DirectionalShadowIndex];
|
||||
HDShadowContext context = InitShadowContext();
|
||||
|
||||
// Zeros are for screen space position and world space normal which are for filtering and normal bias
|
||||
// respectively. They did not appear to have an impact.
|
||||
half shadows = GetDirectionalShadowAttenuation(context, 0, i_positionWS.xyz, 0, _DirectionalShadowIndex, -light.forward);
|
||||
// Apply shadow strength from main light.
|
||||
shadows = LerpWhiteTo(shadows, light.shadowDimmer);
|
||||
|
||||
return shadows;
|
||||
}
|
||||
|
||||
half ComputeShadowFade(const float4 i_positionWS)
|
||||
{
|
||||
// TODO: Work out shadow fade.
|
||||
return 0.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if _URP
|
||||
half SampleShadows(const float4 i_positionWS)
|
||||
{
|
||||
// Includes soft shadows if _SHADOWS_SOFT is defined (requires multi-compile pragma).
|
||||
return MainLightRealtimeShadow(TransformWorldToShadowCoord(i_positionWS.xyz));
|
||||
}
|
||||
|
||||
half ComputeShadowFade(const float4 i_positionWS)
|
||||
{
|
||||
return GetShadowFade(i_positionWS.xyz);
|
||||
}
|
||||
#endif
|
||||
|
||||
m_UtilityNameSpaceEnd
|
||||
|
||||
#endif // d_WaveHarmonic_Utility_RenderPipeline_Shadows
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07d6b2cd79ac04fa5b56cffd5fb1bb31
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,85 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
#ifndef CREST_SHADOWS_H
|
||||
#define CREST_SHADOWS_H
|
||||
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Macros.hlsl"
|
||||
#include "Packages/com.waveharmonic.crest/Runtime/Shaders/Library/Globals.hlsl"
|
||||
|
||||
#if CREST_BIRP
|
||||
TEXTURE2D_X(_Crest_ScreenSpaceShadowTexture);
|
||||
float4 _Crest_ScreenSpaceShadowTexture_TexelSize;
|
||||
#endif // CREST_BIRP
|
||||
|
||||
#if CREST_URP
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
#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 // CREST_HDRP_FORWARD_PASS
|
||||
#endif // SHADERGRAPH_PREVIEW
|
||||
#endif // CREST_HDRP
|
||||
|
||||
m_CrestNameSpace
|
||||
|
||||
// Position: SRP = WS / BIRP = SS (z ignored)
|
||||
half PrimaryLightShadows(const float3 i_Position, const float2 i_ScreenPosition)
|
||||
{
|
||||
// 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_ScreenPosition, _Crest_ScreenSpaceShadowTexture_TexelSize.zw - 1.0)).r;
|
||||
#if DIRECTIONAL_COOKIE
|
||||
const half attenuation = tex2D(_LightTexture0, mul(unity_WorldToLight, float4(i_Position, 1.0)).xy).w;
|
||||
shadow = min(attenuation, shadow);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return shadow;
|
||||
}
|
||||
|
||||
m_CrestNameSpaceEnd
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4623a51d04ef4e9c82e9196bf28e48d
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user