Files
UnrealEngine/Engine/Shaders/Private/ForwardShadowingCommon.ush
2025-05-18 13:04:45 +08:00

104 lines
4.6 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
ForwardShadowingCommon.ush
=============================================================================*/
#include "ShadowFilteringCommon.ush"
float ComputeDirectionalLightStaticShadowing(float3 TranslatedWorldPosition)
{
float ShadowFactor = 1;
#if ALLOW_STATIC_LIGHTING
BRANCH
if (ForwardLightStruct.DirectionalLightUseStaticShadowing > 0)
{
// Transform the world position into shadowmap space
float4 HomogeneousShadowPosition = mul(float4(TranslatedWorldPosition, 1), ForwardLightStruct.DirectionalLightTranslatedWorldToStaticShadow);
float2 ShadowUVs = HomogeneousShadowPosition.xy / HomogeneousShadowPosition.w;
// Treat as unshadowed if the voxel is outside of the shadow map
if (all(and(ShadowUVs >= 0, ShadowUVs <= 1)))
{
#define FILTER_STATIC_SHADOWING 0
#if FILTER_STATIC_SHADOWING
FPCFSamplerSettings Settings;
Settings.ShadowDepthTexture = ForwardLightStruct.DirectionalLightStaticShadowmap;
Settings.ShadowDepthTextureSampler = ForwardLightStruct.StaticShadowmapSampler;
Settings.ShadowBufferSize = ForwardLightStruct.DirectionalLightStaticShadowBufferSize;
Settings.SceneDepth = 1 - HomogeneousShadowPosition.z;
Settings.TransitionScale = 40;
Settings.bSubsurface = false;
// We can sample outside of the static shadowmap, which is centered around the lightmass importance volume. These 'infinite' depth values should not cause occlusion.
Settings.bTreatMaxDepthUnshadowed = true;
Settings.DensityMulConstant = 0;
Settings.ProjectionDepthBiasParameters = float2(0, 0);
ShadowFactor = Manual1x1PCF(ShadowUVs, Settings);
#else
// Sample the shadowmap depth and determine if this voxel is shadowed
float ShadowDepth = Texture2DSampleLevel(ForwardLightStruct.DirectionalLightStaticShadowmap, ForwardLightStruct.StaticShadowmapSampler, ShadowUVs, 0).x;
ShadowFactor = HomogeneousShadowPosition.z < ShadowDepth || ShadowDepth > .99f;
#endif
}
}
#endif
return ShadowFactor;
}
#ifndef FILTER_DIRECTIONAL_LIGHT_SHADOWING
#define FILTER_DIRECTIONAL_LIGHT_SHADOWING 0
#endif
uint GetForwardLightingCascadeIndex(float4 CascadeEndDepths, float SceneDepth)
{
float4 Count = float4(SceneDepth.xxxx >= CascadeEndDepths);
return uint(Count.x + Count.y + Count.z + Count.w);
}
float ComputeDirectionalLightDynamicShadowing(float3 TranslatedWorldPosition, float SceneDepth, inout bool bShadowingFromValidUVArea)
{
float ShadowFactor = 1;
bShadowingFromValidUVArea = false;
const uint NumCascades = ForwardLightStruct.NumDirectionalLightCascades;
if (NumCascades > 0)
{
uint CascadeIndex = GetForwardLightingCascadeIndex(ForwardLightStruct.CascadeEndDepths, SceneDepth);
if (CascadeIndex < NumCascades)
{
// Transform the world position into shadowmap space
float4 HomogeneousShadowPosition = mul(float4(TranslatedWorldPosition, 1), ForwardLightStruct.DirectionalLightTranslatedWorldToShadowMatrix[CascadeIndex]);
float2 ShadowUVs = HomogeneousShadowPosition.xy / HomogeneousShadowPosition.w;
float4 ShadowmapMinMax = ForwardLightStruct.DirectionalLightShadowmapMinMax[CascadeIndex];
// Treat as unshadowed if the voxel is outside of the shadow map
if (all(and(ShadowUVs >= ShadowmapMinMax.xy, ShadowUVs <= ShadowmapMinMax.zw)))
{
#if FILTER_DIRECTIONAL_LIGHT_SHADOWING
FPCFSamplerSettings Settings;
Settings.ShadowDepthTexture = ForwardLightStruct.DirectionalLightShadowmapAtlas;
Settings.ShadowDepthTextureSampler = ForwardLightStruct.ShadowmapSampler;
Settings.ShadowBufferSize = ForwardLightStruct.DirectionalLightShadowmapAtlasBufferSize;
Settings.SceneDepth = 1 - HomogeneousShadowPosition.z;
Settings.TransitionScale = 4000;
Settings.bSubsurface = false;
Settings.bTreatMaxDepthUnshadowed = false;
Settings.DensityMulConstant = 0;
Settings.ProjectionDepthBiasParameters = float2(0, 0);
ShadowFactor = Manual1x1PCF(ShadowUVs, Settings);
#else
// Sample the shadowmap depth and determine if this voxel is shadowed
float ShadowDepth = Texture2DSampleLevel(ForwardLightStruct.DirectionalLightShadowmapAtlas, ForwardLightStruct.ShadowmapSampler, ShadowUVs, 0).x;
ShadowFactor = 1 - HomogeneousShadowPosition.z < ShadowDepth - ForwardLightStruct.DirectionalLightDepthBias.x;
#endif
// Note this doesn't actually mean the shadow factor computed is valid, eg CSM culling removes meshes which would cast on off-screen areas of the shadowmap, which still have valid UVs
bShadowingFromValidUVArea = true;
}
}
}
return ShadowFactor;
}