Files
2026-01-08 22:30:55 +08:00

108 lines
3.7 KiB
HLSL

// 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