104 lines
4.6 KiB
HLSL
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;
|
|
} |