2020-07-06 18:58:26 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
VirtualShadowMapProjection . cpp
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "VirtualShadowMapProjection.h"
# include "CoreMinimal.h"
# include "Stats/Stats.h"
# include "RHI.h"
# include "RenderResource.h"
# include "RendererInterface.h"
# include "Shader.h"
# include "StaticBoundShaderState.h"
# include "SceneUtils.h"
# include "RHIStaticStates.h"
# include "LightSceneInfo.h"
# include "GlobalShader.h"
# include "SceneRenderTargetParameters.h"
# include "ShadowRendering.h"
# include "DeferredShadingRenderer.h"
# include "PixelShaderUtils.h"
# include "ShadowRendering.h"
# include "SceneRendering.h"
# include "VirtualShadowMapClipmap.h"
static TAutoConsoleVariable < float > CVarContactShadowLength (
2021-02-18 13:44:36 -04:00
TEXT ( " r.Shadow.Virtual.ContactShadowLength " ) ,
2021-01-08 22:26:52 -04:00
0.02f ,
2020-07-06 18:58:26 -04:00
TEXT ( " Length of the screen space contact shadow trace (smart shadow bias) before the virtual shadow map lookup. " ) ,
ECVF_RenderThreadSafe
) ;
2021-01-08 22:26:52 -04:00
static TAutoConsoleVariable < float > CVarNormalOffsetWorld (
2021-02-18 13:44:36 -04:00
TEXT ( " r.Shadow.Virtual.NormalOffsetWorld " ) ,
2021-01-14 20:00:54 -04:00
0.1f ,
2021-01-08 22:26:52 -04:00
TEXT ( " World space offset along surface normal for shadow lookup. " )
TEXT ( " Higher values avoid artifacts on surfaces nearly parallel to the light, but also visibility offset shadows and increase the chance of hitting unmapped pages. " ) ,
ECVF_RenderThreadSafe
) ;
2020-07-06 18:58:26 -04:00
static TAutoConsoleVariable < int32 > CVarVirtualShadowMapDebugProjection (
2021-02-18 21:09:05 -04:00
TEXT ( " r.Shadow.Virtual.DebugProjection " ) ,
2020-07-06 18:58:26 -04:00
0 ,
2021-02-18 21:09:05 -04:00
TEXT ( " Projection pass debug output visualization for use with 'vis Shadow.Virtual.DebugProjection'. " ) ,
2020-07-06 18:58:26 -04:00
ECVF_RenderThreadSafe
) ;
2021-01-25 18:20:37 -04:00
TAutoConsoleVariable < int32 > CVarVirtualShadowOnePassProjection (
2021-02-18 13:44:36 -04:00
TEXT ( " r.Shadow.Virtual.OnePassProjection " ) ,
2021-01-25 18:20:37 -04:00
0 ,
TEXT ( " Single pass projects all local VSMs culled with the light grid. Used in conjunction with clustered deferred shading. " ) ,
ECVF_RenderThreadSafe
) ;
2021-02-05 15:55:43 -04:00
static TAutoConsoleVariable < int32 > CVarSMRTRayCountLocal (
2021-02-18 13:44:36 -04:00
TEXT ( " r.Shadow.Virtual.SMRT.RayCountLocal " ) ,
2021-02-05 15:55:43 -04:00
0 ,
TEXT ( " Ray count for shadow map tracing of local lights. 0 = disabled. " ) ,
ECVF_RenderThreadSafe
) ;
static TAutoConsoleVariable < int32 > CVarSMRTSamplesPerRayLocal (
2021-02-18 13:44:36 -04:00
TEXT ( " r.Shadow.Virtual.SMRT.SamplesPerRayLocal " ) ,
2021-02-05 15:55:43 -04:00
16 ,
TEXT ( " Shadow map samples per ray for local lights " ) ,
ECVF_RenderThreadSafe
) ;
static TAutoConsoleVariable < float > CVarSMRTMaxRayAngleFromLight (
2021-02-18 13:44:36 -04:00
TEXT ( " r.Shadow.Virtual.SMRT.MaxRayAngleFromLight " ) ,
2021-02-05 15:55:43 -04:00
0.03f ,
TEXT ( " Max angle (in radians) a ray is allowed to span from the light's perspective for local lights. " )
TEXT ( " Smaller angles limit the screen space size of shadow penumbra. " )
TEXT ( " Larger angles lead to more noise. " ) ,
ECVF_RenderThreadSafe
) ;
2020-12-16 17:57:13 -04:00
static TAutoConsoleVariable < int32 > CVarSMRTRayCountDirectional (
2021-02-18 13:44:36 -04:00
TEXT ( " r.Shadow.Virtual.SMRT.RayCountDirectional " ) ,
2020-12-16 17:57:13 -04:00
0 ,
TEXT ( " Ray count for shadow map tracing of directional lights. 0 = disabled. " ) ,
ECVF_RenderThreadSafe
) ;
static TAutoConsoleVariable < int32 > CVarSMRTSamplesPerRayDirectional (
2021-02-18 13:44:36 -04:00
TEXT ( " r.Shadow.Virtual.SMRT.SamplesPerRayDirectional " ) ,
2020-12-16 17:57:13 -04:00
12 ,
TEXT ( " Shadow map samples per ray for directional lights " ) ,
ECVF_RenderThreadSafe
) ;
static TAutoConsoleVariable < float > CVarSMRTRayLengthScaleDirectional (
2021-02-18 13:44:36 -04:00
TEXT ( " r.Shadow.Virtual.SMRT.RayLengthScaleDirectional " ) ,
2021-01-08 22:26:52 -04:00
1.0f ,
2020-12-16 17:57:13 -04:00
TEXT ( " Length of ray to shoot for directional lights, scaled by distance to camera. " )
TEXT ( " Shorter rays limit the screen space size of shadow penumbra. " )
TEXT ( " Longer rays require more samples to avoid shadows disconnecting from contact points. " ) ,
ECVF_RenderThreadSafe
) ;
2021-01-27 21:04:55 -04:00
static TAutoConsoleVariable < int32 > CVarSMRTAdaptiveRayCount (
2021-02-18 13:44:36 -04:00
TEXT ( " r.Shadow.Virtual.SMRT.AdaptiveRayCount " ) ,
2021-01-27 21:04:55 -04:00
1 ,
TEXT ( " Shoot fewer rays in fully shadowed and unshadowed regions. Currently only supported with OnePassProjection. " ) ,
ECVF_RenderThreadSafe
) ;
2020-08-27 14:20:18 -04:00
BEGIN_SHADER_PARAMETER_STRUCT ( FProjectionParameters , )
2020-08-27 20:31:32 -04:00
SHADER_PARAMETER_STRUCT_INCLUDE ( FVirtualShadowMapSamplingParameters , ProjectionParameters )
2020-07-06 18:58:26 -04:00
SHADER_PARAMETER_STRUCT ( FLightShaderParameters , Light )
2020-11-05 16:28:34 -04:00
SHADER_PARAMETER_RDG_UNIFORM_BUFFER ( FSceneTextureUniformParameters , SceneTexturesStruct )
2020-07-06 18:58:26 -04:00
SHADER_PARAMETER_STRUCT_REF ( FViewUniformShaderParameters , View )
2020-08-27 14:20:18 -04:00
SHADER_PARAMETER ( int32 , VirtualShadowMapId )
2020-07-06 18:58:26 -04:00
SHADER_PARAMETER ( float , ContactShadowLength )
2021-01-08 22:26:52 -04:00
SHADER_PARAMETER ( float , NormalOffsetWorld )
2020-07-06 18:58:26 -04:00
SHADER_PARAMETER ( int32 , DebugOutputType )
2020-12-16 17:57:13 -04:00
SHADER_PARAMETER ( int32 , SMRTRayCount )
SHADER_PARAMETER ( int32 , SMRTSamplesPerRay )
SHADER_PARAMETER ( float , SMRTRayLengthScale )
2021-02-05 15:55:43 -04:00
SHADER_PARAMETER ( float , SMRTCotMaxRayAngleFromLight )
2020-07-06 18:58:26 -04:00
RENDER_TARGET_BINDING_SLOTS ( )
END_SHADER_PARAMETER_STRUCT ( )
2020-12-16 17:57:13 -04:00
class FVirtualShadowMapProjectionSpotPS : public FGlobalShader
2020-07-06 18:58:26 -04:00
{
2020-12-16 17:57:13 -04:00
DECLARE_GLOBAL_SHADER ( FVirtualShadowMapProjectionSpotPS ) ;
SHADER_USE_PARAMETER_STRUCT ( FVirtualShadowMapProjectionSpotPS , FGlobalShader ) ;
2020-08-19 14:22:37 -04:00
2020-07-06 18:58:26 -04:00
class FOutputTypeDim : SHADER_PERMUTATION_ENUM_CLASS ( " OUTPUT_TYPE " , EVirtualShadowMapProjectionOutputType ) ;
using FPermutationDomain = TShaderPermutationDomain < FOutputTypeDim > ;
2020-08-27 14:20:18 -04:00
using FParameters = FProjectionParameters ;
2020-07-06 18:58:26 -04:00
2020-08-19 14:22:37 -04:00
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters )
{
return DoesPlatformSupportNanite ( Parameters . Platform ) ;
}
2020-07-06 18:58:26 -04:00
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FVirtualShadowMapArray : : SetShaderDefines ( OutEnvironment ) ;
}
} ;
2020-12-16 17:57:13 -04:00
IMPLEMENT_GLOBAL_SHADER ( FVirtualShadowMapProjectionSpotPS , " /Engine/Private/VirtualShadowMaps/VirtualShadowMapProjection.usf " , " VirtualShadowMapProjectionSpotPS " , SF_Pixel ) ;
class FVirtualShadowMapProjectionDirectionalPS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER ( FVirtualShadowMapProjectionDirectionalPS ) ;
SHADER_USE_PARAMETER_STRUCT ( FVirtualShadowMapProjectionDirectionalPS , FGlobalShader ) ;
class FOutputTypeDim : SHADER_PERMUTATION_ENUM_CLASS ( " OUTPUT_TYPE " , EVirtualShadowMapProjectionOutputType ) ;
using FPermutationDomain = TShaderPermutationDomain < FOutputTypeDim > ;
using FParameters = FProjectionParameters ;
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters )
{
return DoesPlatformSupportNanite ( Parameters . Platform ) ;
}
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FVirtualShadowMapArray : : SetShaderDefines ( OutEnvironment ) ;
}
} ;
IMPLEMENT_GLOBAL_SHADER ( FVirtualShadowMapProjectionDirectionalPS , " /Engine/Private/VirtualShadowMaps/VirtualShadowMapProjection.usf " , " VirtualShadowMapProjectionDirectionalPS " , SF_Pixel ) ;
2020-07-06 18:58:26 -04:00
BEGIN_SHADER_PARAMETER_STRUCT ( FVirtualShadowMapProjectionCompositeParameters , )
SHADER_PARAMETER_RDG_TEXTURE ( Texture2D < float4 > , InputSignal )
RENDER_TARGET_BINDING_SLOTS ( )
END_SHADER_PARAMETER_STRUCT ( )
// Composite denoised shadow projection mask onto the light's shadow mask
// Basically just a copy shader with a special blend mode
class FVirtualShadowMapProjectionCompositePS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER ( FVirtualShadowMapProjectionCompositePS ) ;
SHADER_USE_PARAMETER_STRUCT ( FVirtualShadowMapProjectionCompositePS , FGlobalShader ) ;
using FParameters = FVirtualShadowMapProjectionCompositeParameters ;
2020-08-19 14:22:37 -04:00
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters )
{
return DoesPlatformSupportNanite ( Parameters . Platform ) ;
}
2020-07-06 18:58:26 -04:00
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
// Required right now due to where the shader function lives, but not actually used
FVirtualShadowMapArray : : SetShaderDefines ( OutEnvironment ) ;
}
} ;
IMPLEMENT_GLOBAL_SHADER ( FVirtualShadowMapProjectionCompositePS , " /Engine/Private/VirtualShadowMaps/VirtualShadowMapProjection.usf " , " VirtualShadowMapCompositePS " , SF_Pixel ) ;
2020-12-16 17:57:13 -04:00
// Returns true if temporal denoising should be used
static bool AddPass_RenderVirtualShadowMapProjection (
2020-07-06 18:58:26 -04:00
const FLightSceneProxy * LightProxy ,
FRDGBuilder & GraphBuilder ,
const FViewInfo & View ,
FVirtualShadowMapArray & VirtualShadowMapArray ,
2020-08-27 14:20:18 -04:00
int VirtualShadowMapId ,
2020-07-06 18:58:26 -04:00
const FIntRect ScissorRect ,
EVirtualShadowMapProjectionOutputType OutputType ,
const FRenderTargetBinding & RenderTargetBinding ,
FRHIBlendState * BlendState )
{
check ( ScissorRect . Area ( ) > 0 ) ;
FGlobalShaderMap * ShaderMap = View . ShaderMap ;
2020-08-27 14:20:18 -04:00
FProjectionParameters * PassParameters = GraphBuilder . AllocParameters < FProjectionParameters > ( ) ;
VirtualShadowMapArray . SetProjectionParameters ( GraphBuilder , PassParameters - > ProjectionParameters ) ;
2020-11-05 16:28:34 -04:00
PassParameters - > SceneTexturesStruct = CreateSceneTextureUniformBuffer ( GraphBuilder , View . FeatureLevel , ESceneTextureSetupMode : : GBuffers | ESceneTextureSetupMode : : SceneDepth ) ;
2020-07-06 18:58:26 -04:00
PassParameters - > View = View . ViewUniformBuffer ;
FLightShaderParameters LightParameters ;
LightProxy - > GetLightShaderParameters ( LightParameters ) ;
PassParameters - > Light = LightParameters ;
2020-08-27 14:20:18 -04:00
PassParameters - > VirtualShadowMapId = VirtualShadowMapId ;
2020-07-06 18:58:26 -04:00
PassParameters - > DebugOutputType = CVarVirtualShadowMapDebugProjection . GetValueOnRenderThread ( ) ;
PassParameters - > ContactShadowLength = CVarContactShadowLength . GetValueOnRenderThread ( ) ;
2021-01-08 22:26:52 -04:00
PassParameters - > NormalOffsetWorld = CVarNormalOffsetWorld . GetValueOnRenderThread ( ) ;
2020-07-06 18:58:26 -04:00
PassParameters - > RenderTargets [ 0 ] = RenderTargetBinding ;
2020-12-16 17:57:13 -04:00
if ( LightProxy - > GetLightType ( ) = = LightType_Directional )
2020-07-06 18:58:26 -04:00
{
2020-12-16 17:57:13 -04:00
PassParameters - > SMRTRayCount = CVarSMRTRayCountDirectional . GetValueOnRenderThread ( ) ;
PassParameters - > SMRTSamplesPerRay = CVarSMRTSamplesPerRayDirectional . GetValueOnRenderThread ( ) ;
PassParameters - > SMRTRayLengthScale = CVarSMRTRayLengthScaleDirectional . GetValueOnRenderThread ( ) ;
2021-02-05 15:55:43 -04:00
PassParameters - > SMRTCotMaxRayAngleFromLight = 0.0f ; // unused in this path
2020-12-16 17:57:13 -04:00
FVirtualShadowMapProjectionDirectionalPS : : FPermutationDomain PermutationVector ;
PermutationVector . Set < FVirtualShadowMapProjectionDirectionalPS : : FOutputTypeDim > ( OutputType ) ;
auto PixelShader = ShaderMap - > GetShader < FVirtualShadowMapProjectionDirectionalPS > ( PermutationVector ) ;
2020-07-06 18:58:26 -04:00
ValidateShaderParameters ( PixelShader , * PassParameters ) ;
// NOTE: We use SV_Position in the shader, so we don't need separate scissor/view rect
FPixelShaderUtils : : AddFullscreenPass ( GraphBuilder ,
ShaderMap ,
2020-12-16 17:57:13 -04:00
( OutputType = = EVirtualShadowMapProjectionOutputType : : Debug ) ? RDG_EVENT_NAME ( " Debug Directional Projection " ) : RDG_EVENT_NAME ( " Directional Projection " ) ,
2020-07-06 18:58:26 -04:00
PixelShader ,
PassParameters ,
ScissorRect ,
BlendState ) ;
2020-12-16 17:57:13 -04:00
// Use temporal denoising with SMRT
return PassParameters - > SMRTRayCount > 0 ;
2020-07-06 18:58:26 -04:00
}
2021-01-18 22:44:41 -04:00
else
2020-12-16 17:57:13 -04:00
{
2021-02-05 15:55:43 -04:00
PassParameters - > SMRTRayCount = CVarSMRTRayCountLocal . GetValueOnRenderThread ( ) ;
PassParameters - > SMRTSamplesPerRay = CVarSMRTSamplesPerRayLocal . GetValueOnRenderThread ( ) ;
PassParameters - > SMRTRayLengthScale = 0.0f ; // unused in this path
PassParameters - > SMRTCotMaxRayAngleFromLight = 1.0f / FMath : : Tan ( CVarSMRTMaxRayAngleFromLight . GetValueOnRenderThread ( ) ) ;
2020-12-16 17:57:13 -04:00
FVirtualShadowMapProjectionSpotPS : : FPermutationDomain PermutationVector ;
PermutationVector . Set < FVirtualShadowMapProjectionSpotPS : : FOutputTypeDim > ( OutputType ) ;
auto PixelShader = ShaderMap - > GetShader < FVirtualShadowMapProjectionSpotPS > ( PermutationVector ) ;
ValidateShaderParameters ( PixelShader , * PassParameters ) ;
// NOTE: We use SV_Position in the shader, so we don't need separate scissor/view rect
FPixelShaderUtils : : AddFullscreenPass ( GraphBuilder ,
ShaderMap ,
( OutputType = = EVirtualShadowMapProjectionOutputType : : Debug ) ? RDG_EVENT_NAME ( " Debug Spot Projection " ) : RDG_EVENT_NAME ( " Spot Projection " ) ,
PixelShader ,
PassParameters ,
ScissorRect ,
BlendState ) ;
// Use temporal denoising with SMRT
return PassParameters - > SMRTRayCount > 0 ;
}
return false ;
2020-07-06 18:58:26 -04:00
}
static FRDGTextureRef CreateDebugOutput ( FRDGBuilder & GraphBuilder , FIntPoint Extent )
{
2020-09-24 00:43:27 -04:00
FRDGTextureDesc DebugOutputDesc = FRDGTextureDesc : : Create2D (
2020-07-06 18:58:26 -04:00
Extent ,
PF_A32B32G32R32F ,
FClearValueBinding : : Transparent ,
2021-02-18 13:44:36 -04:00
TexCreate_ShaderResource | TexCreate_RenderTargetable
) ;
2021-02-18 21:09:05 -04:00
return GraphBuilder . CreateTexture ( DebugOutputDesc , TEXT ( " Shadow.Virtual.DebugProjection " ) ) ;
2020-07-06 18:58:26 -04:00
}
2020-12-16 17:57:13 -04:00
// Returns true if temporal denoising should be used
static bool RenderVirtualShadowMapProjectionCommon (
2020-07-06 18:58:26 -04:00
const FLightSceneProxy * LightProxy ,
FRDGBuilder & GraphBuilder ,
const FViewInfo & View ,
FVirtualShadowMapArray & VirtualShadowMapArray ,
2020-08-27 14:20:18 -04:00
int32 VirtualShadowMapId ,
2020-07-06 18:58:26 -04:00
const FIntRect ScissorRect ,
EVirtualShadowMapProjectionOutputType OutputType ,
const FRenderTargetBinding & RenderTargetBinding ,
FRHIBlendState * BlendState )
{
// Main Pass
2020-12-16 17:57:13 -04:00
bool bOutUseTemporalDenoising = AddPass_RenderVirtualShadowMapProjection (
2020-08-27 14:20:18 -04:00
LightProxy ,
2020-07-06 18:58:26 -04:00
GraphBuilder ,
View ,
VirtualShadowMapArray ,
2020-08-27 14:20:18 -04:00
VirtualShadowMapId ,
2020-07-06 18:58:26 -04:00
ScissorRect ,
OutputType ,
RenderTargetBinding ,
BlendState ) ;
// Debug visualization
const int32 DebugVisualize = CVarVirtualShadowMapDebugProjection . GetValueOnRenderThread ( ) ;
if ( DebugVisualize > 0 )
{
FRDGTextureRef DebugOutput = CreateDebugOutput ( GraphBuilder , View . ViewRect . Max ) ;
FRenderTargetBinding DebugRenderTargetBinding ( DebugOutput , ERenderTargetLoadAction : : EClear ) ;
AddPass_RenderVirtualShadowMapProjection (
2020-08-27 14:20:18 -04:00
LightProxy ,
2020-07-06 18:58:26 -04:00
GraphBuilder ,
View ,
VirtualShadowMapArray ,
2020-08-27 14:20:18 -04:00
VirtualShadowMapId ,
2020-07-06 18:58:26 -04:00
ScissorRect ,
EVirtualShadowMapProjectionOutputType : : Debug ,
DebugRenderTargetBinding ,
nullptr ) ;
GraphBuilder . QueueTextureExtraction ( DebugOutput , & VirtualShadowMapArray . DebugVisualizationProjectionOutput ) ;
}
2020-12-16 17:57:13 -04:00
return bOutUseTemporalDenoising ;
2020-07-06 18:58:26 -04:00
}
void RenderVirtualShadowMapProjectionForDenoising (
2020-08-20 14:06:29 -04:00
FProjectedShadowInfo * ShadowInfo ,
2020-07-06 18:58:26 -04:00
FRDGBuilder & GraphBuilder ,
const FViewInfo & View ,
FVirtualShadowMapArray & VirtualShadowMapArray ,
const FIntRect ScissorRect ,
2020-12-16 17:57:13 -04:00
FRDGTextureRef SignalTexture ,
bool & bOutUseTemporalDenoising )
2020-07-06 18:58:26 -04:00
{
FRenderTargetBinding RenderTargetBinding ( SignalTexture , ERenderTargetLoadAction : : EClear ) ;
2020-12-16 17:57:13 -04:00
bOutUseTemporalDenoising = RenderVirtualShadowMapProjectionCommon (
2020-08-27 14:20:18 -04:00
ShadowInfo - > GetLightSceneInfo ( ) . Proxy ,
2020-07-06 18:58:26 -04:00
GraphBuilder ,
View ,
VirtualShadowMapArray ,
2021-01-18 22:44:41 -04:00
ShadowInfo - > VirtualShadowMaps [ 0 ] - > ID ,
2020-07-06 18:58:26 -04:00
ScissorRect ,
EVirtualShadowMapProjectionOutputType : : Denoiser ,
RenderTargetBinding ,
nullptr ) ;
}
void RenderVirtualShadowMapProjectionForDenoising (
const TSharedPtr < FVirtualShadowMapClipmap > & Clipmap ,
FRDGBuilder & GraphBuilder ,
const FViewInfo & View ,
FVirtualShadowMapArray & VirtualShadowMapArray ,
const FIntRect ScissorRect ,
2020-12-16 17:57:13 -04:00
FRDGTextureRef SignalTexture ,
bool & bOutUseTemporalDenoising )
2020-08-27 14:20:18 -04:00
{
2020-07-06 18:58:26 -04:00
FRenderTargetBinding RenderTargetBinding ( SignalTexture , ERenderTargetLoadAction : : EClear ) ;
2020-12-16 17:57:13 -04:00
bOutUseTemporalDenoising = RenderVirtualShadowMapProjectionCommon (
2020-08-27 14:20:18 -04:00
Clipmap - > GetLightSceneInfo ( ) . Proxy ,
2020-07-06 18:58:26 -04:00
GraphBuilder ,
View ,
VirtualShadowMapArray ,
2020-08-27 14:20:18 -04:00
Clipmap - > GetVirtualShadowMap ( ) - > ID ,
2020-07-06 18:58:26 -04:00
ScissorRect ,
EVirtualShadowMapProjectionOutputType : : Denoiser ,
RenderTargetBinding ,
nullptr ) ;
}
void RenderVirtualShadowMapProjection (
2020-08-20 14:06:29 -04:00
FProjectedShadowInfo * ShadowInfo ,
2020-07-06 18:58:26 -04:00
FRDGBuilder & GraphBuilder ,
const FViewInfo & View ,
FVirtualShadowMapArray & VirtualShadowMapArray ,
const FIntRect ScissorRect ,
FRDGTextureRef ScreenShadowMaskTexture ,
bool bProjectingForForwardShading )
{
FRenderTargetBinding RenderTargetBinding ( ScreenShadowMaskTexture , ERenderTargetLoadAction : : ELoad ) ;
2020-08-20 14:06:29 -04:00
FRHIBlendState * BlendState = ShadowInfo - > GetBlendStateForProjection ( bProjectingForForwardShading , false ) ;
2020-07-06 18:58:26 -04:00
RenderVirtualShadowMapProjectionCommon (
2020-08-27 14:20:18 -04:00
ShadowInfo - > GetLightSceneInfo ( ) . Proxy ,
2020-07-06 18:58:26 -04:00
GraphBuilder ,
View ,
VirtualShadowMapArray ,
2021-01-18 22:44:41 -04:00
ShadowInfo - > VirtualShadowMaps [ 0 ] - > ID ,
2020-07-06 18:58:26 -04:00
ScissorRect ,
EVirtualShadowMapProjectionOutputType : : ScreenShadowMask ,
RenderTargetBinding ,
BlendState ) ;
}
void RenderVirtualShadowMapProjection (
const TSharedPtr < FVirtualShadowMapClipmap > & Clipmap ,
FRDGBuilder & GraphBuilder ,
const FViewInfo & View ,
FVirtualShadowMapArray & VirtualShadowMapArray ,
const FIntRect ScissorRect ,
FRDGTextureRef ScreenShadowMaskTexture ,
bool bProjectingForForwardShading )
{
2020-08-27 14:20:18 -04:00
FRenderTargetBinding RenderTargetBinding ( ScreenShadowMaskTexture , ERenderTargetLoadAction : : ELoad ) ;
2020-07-06 18:58:26 -04:00
// See FProjectedShadowInfo::GetBlendStateForProjection. TODO: Support other modes in this path?
FRHIBlendState * BlendState = TStaticBlendState < CW_BA , BO_Min , BF_One , BF_One , BO_Min , BF_One , BF_One > : : GetRHI ( ) ;
RenderVirtualShadowMapProjectionCommon (
2020-08-27 14:20:18 -04:00
Clipmap - > GetLightSceneInfo ( ) . Proxy ,
2020-07-06 18:58:26 -04:00
GraphBuilder ,
View ,
VirtualShadowMapArray ,
2020-08-27 14:20:18 -04:00
Clipmap - > GetVirtualShadowMap ( ) - > ID ,
2020-07-06 18:58:26 -04:00
ScissorRect ,
EVirtualShadowMapProjectionOutputType : : ScreenShadowMask ,
RenderTargetBinding ,
BlendState ) ;
}
void CompositeVirtualShadowMapMask (
FRDGBuilder & GraphBuilder ,
const FIntRect ScissorRect ,
const FSSDSignalTextures & InputSignal ,
FRDGTextureRef OutputShadowMaskTexture )
{
auto ShaderMap = GetGlobalShaderMap ( GMaxRHIFeatureLevel ) ;
FVirtualShadowMapProjectionCompositeParameters * PassParameters = GraphBuilder . AllocParameters < FVirtualShadowMapProjectionCompositeParameters > ( ) ;
PassParameters - > InputSignal = InputSignal . Textures [ 0 ] ;
PassParameters - > RenderTargets [ 0 ] = FRenderTargetBinding ( OutputShadowMaskTexture , ERenderTargetLoadAction : : ELoad ) ;
// See FProjectedShadowInfo::GetBlendStateForProjection, but we don't want any of the special cascade behavior, etc. as this is a post-denoised mask.
FRHIBlendState * BlendState = TStaticBlendState < CW_BA , BO_Min , BF_One , BF_One , BO_Min , BF_One , BF_One > : : GetRHI ( ) ;
auto PixelShader = ShaderMap - > GetShader < FVirtualShadowMapProjectionCompositePS > ( ) ;
ValidateShaderParameters ( PixelShader , * PassParameters ) ;
FPixelShaderUtils : : AddFullscreenPass ( GraphBuilder ,
ShaderMap ,
RDG_EVENT_NAME ( " Mask Composite " ) ,
PixelShader ,
PassParameters ,
ScissorRect ,
BlendState ) ;
}
2021-01-25 18:20:37 -04:00
class FVirtualShadowMapProjectionCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER ( FVirtualShadowMapProjectionCS ) ;
SHADER_USE_PARAMETER_STRUCT ( FVirtualShadowMapProjectionCS , FGlobalShader )
2021-01-27 21:04:55 -04:00
class FSMRTAdaptiveRayCountDim : SHADER_PERMUTATION_BOOL ( " SMRT_ADAPTIVE_RAY_COUNT " ) ;
using FPermutationDomain = TShaderPermutationDomain < FSMRTAdaptiveRayCountDim > ;
2021-01-25 18:20:37 -04:00
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
SHADER_PARAMETER_STRUCT_INCLUDE ( FVirtualShadowMapSamplingParameters , ProjectionParameters )
SHADER_PARAMETER_RDG_UNIFORM_BUFFER ( FSceneTextureUniformParameters , SceneTexturesStruct )
SHADER_PARAMETER_STRUCT_REF ( FViewUniformShaderParameters , View )
SHADER_PARAMETER_STRUCT_REF ( FForwardLightData , ForwardLightData )
SHADER_PARAMETER_RDG_BUFFER_SRV ( StructuredBuffer < FVirtualShadowMapProjectionShaderData > , ShadowMapProjectionData )
SHADER_PARAMETER_RDG_BUFFER_SRV ( StructuredBuffer < uint > , VirtualShadowMapIdRemap )
SHADER_PARAMETER_RDG_TEXTURE_UAV ( RWTexture2D < uint > , RWShadowMaskBits )
SHADER_PARAMETER ( uint32 , NumDirectionalLightSmInds )
SHADER_PARAMETER ( float , ContactShadowLength )
SHADER_PARAMETER ( float , NormalOffsetWorld )
SHADER_PARAMETER ( int32 , DebugOutputType )
SHADER_PARAMETER ( int32 , SMRTRayCount )
SHADER_PARAMETER ( int32 , SMRTSamplesPerRay )
SHADER_PARAMETER ( float , SMRTRayLengthScale )
2021-02-05 15:55:43 -04:00
SHADER_PARAMETER ( float , SMRTCotMaxRayAngleFromLight )
2021-01-25 18:20:37 -04:00
END_SHADER_PARAMETER_STRUCT ( )
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
FVirtualShadowMapArray : : SetShaderDefines ( OutEnvironment ) ;
FForwardLightingParameters : : ModifyCompilationEnvironment ( Parameters . Platform , OutEnvironment ) ;
2021-01-28 22:04:53 -04:00
FPermutationDomain PermutationVector ( Parameters . PermutationId ) ;
if ( PermutationVector . Get < FSMRTAdaptiveRayCountDim > ( ) )
{
OutEnvironment . CompilerFlags . Add ( CFLAG_WaveOperations ) ;
}
2021-01-25 18:20:37 -04:00
}
2021-01-26 08:59:57 -04:00
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters )
{
return DoesPlatformSupportNanite ( Parameters . Platform ) ;
}
2021-01-25 18:20:37 -04:00
} ;
IMPLEMENT_GLOBAL_SHADER ( FVirtualShadowMapProjectionCS , " /Engine/Private/VirtualShadowMaps/VirtualShadowMapProjection.usf " , " VirtualShadowMapProjection " , SF_Compute ) ;
void RenderVirtualShadowMapProjection (
FRDGBuilder & GraphBuilder ,
const FMinimalSceneTextures & SceneTextures ,
const FViewInfo & View ,
FVirtualShadowMapArray & VirtualShadowMapArray ,
FRDGTextureRef ShadowMaskBits )
{
FVirtualShadowMapProjectionCS : : FParameters * PassParameters = GraphBuilder . AllocParameters < FVirtualShadowMapProjectionCS : : FParameters > ( ) ;
VirtualShadowMapArray . SetProjectionParameters ( GraphBuilder , PassParameters - > ProjectionParameters ) ;
PassParameters - > SceneTexturesStruct = SceneTextures . UniformBuffer ;
PassParameters - > View = View . ViewUniformBuffer ;
PassParameters - > ForwardLightData = View . ForwardLightingResources - > ForwardLightDataUniformBuffer ;
PassParameters - > VirtualShadowMapIdRemap = GraphBuilder . CreateSRV ( VirtualShadowMapArray . VirtualShadowMapIdRemapRDG [ 0 ] ) ; // FIXME Index proper view
PassParameters - > NumDirectionalLightSmInds = VirtualShadowMapArray . NumDirectionalLights ;
PassParameters - > DebugOutputType = CVarVirtualShadowMapDebugProjection . GetValueOnRenderThread ( ) ;
PassParameters - > ContactShadowLength = CVarContactShadowLength . GetValueOnRenderThread ( ) ;
PassParameters - > NormalOffsetWorld = CVarNormalOffsetWorld . GetValueOnRenderThread ( ) ;
2021-02-05 15:55:43 -04:00
PassParameters - > SMRTRayCount = CVarSMRTRayCountLocal . GetValueOnRenderThread ( ) ;
PassParameters - > SMRTSamplesPerRay = CVarSMRTSamplesPerRayLocal . GetValueOnRenderThread ( ) ;
2021-01-25 18:20:37 -04:00
PassParameters - > SMRTRayLengthScale = 0.0f ; // Currently unused in this path
2021-02-05 15:55:43 -04:00
PassParameters - > SMRTCotMaxRayAngleFromLight = 1.0f / FMath : : Tan ( CVarSMRTMaxRayAngleFromLight . GetValueOnRenderThread ( ) ) ;
2021-01-25 18:20:37 -04:00
PassParameters - > RWShadowMaskBits = GraphBuilder . CreateUAV ( ShadowMaskBits ) ;
2021-01-27 21:04:55 -04:00
2021-02-09 17:01:35 -04:00
bool bAdaptiveRayCount = GRHISupportsWaveOperations & & CVarSMRTAdaptiveRayCount . GetValueOnRenderThread ( ) ! = 0 ;
2021-01-27 21:04:55 -04:00
FVirtualShadowMapProjectionCS : : FPermutationDomain PermutationVector ;
2021-02-09 17:01:35 -04:00
PermutationVector . Set < FVirtualShadowMapProjectionCS : : FSMRTAdaptiveRayCountDim > ( bAdaptiveRayCount ) ;
2021-01-27 21:04:55 -04:00
auto ComputeShader = View . ShaderMap - > GetShader < FVirtualShadowMapProjectionCS > ( PermutationVector ) ;
2021-01-25 18:20:37 -04:00
const FIntPoint GroupCount = FIntPoint : : DivideAndRoundUp ( View . ViewRect . Size ( ) , 8 ) ;
FComputeShaderUtils : : AddPass (
GraphBuilder ,
2021-02-09 17:01:35 -04:00
bAdaptiveRayCount ? RDG_EVENT_NAME ( " VirtualShadowMapProjection " ) : RDG_EVENT_NAME ( " VirtualShadowMapProjection (StaticRayCount) " ) ,
2021-01-25 18:20:37 -04:00
ComputeShader ,
PassParameters ,
FIntVector ( GroupCount . X , GroupCount . Y , 1 )
) ;
2021-01-27 21:04:55 -04:00
}