2021-05-26 04:46:16 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "DebugProbeRendering.h"
# include "PixelShaderUtils.h"
# include "ShaderParameterStruct.h"
2021-05-31 16:19:28 -04:00
# include "SceneRendering.h"
2021-06-01 04:03:25 -04:00
# include "SceneTextures.h"
# include "SceneTextureParameters.h"
2021-05-31 16:19:28 -04:00
# include "Strata/Strata.h"
2021-05-26 04:46:16 -04:00
2022-07-07 08:46:49 -04:00
// We do not want such debug in shipping build or when the editor is not available.
# define DEBUG_PROBE_ENABLED (!UE_BUILD_SHIPPING && WITH_EDITORONLY_DATA)
2022-07-01 05:35:21 -04:00
2022-02-16 08:50:28 -05:00
//
// Deferred probes are only stamped in deferred mode.
//
2021-05-26 04:46:16 -04:00
// Changing this causes a full shader recompile
2021-05-31 08:56:02 -04:00
static TAutoConsoleVariable < int32 > CVarVisualizeLightingOnProbes (
TEXT ( " r.VisualizeLightingOnProbes " ) ,
2021-05-26 04:46:16 -04:00
0 ,
2021-05-31 08:56:02 -04:00
TEXT ( " Enables debug probes rendering to visualise diffuse/specular lighting (direct and indirect) on simple sphere scattered in the world. " ) \
2021-05-26 04:46:16 -04:00
TEXT ( " 0: disabled. \n " )
TEXT ( " 1: camera probes only. \n " )
TEXT ( " 2: world probes only. \n " )
TEXT ( " 3: camera and world probes. \n " )
,
ECVF_RenderThreadSafe ) ;
DECLARE_GPU_STAT ( StampDeferredDebugProbe ) ;
2022-07-06 14:43:32 -04:00
extern bool IsIlluminanceMeterSupportedByView ( const FViewInfo & View ) ;
2021-05-26 04:46:16 -04:00
2021-05-31 16:19:28 -04:00
// Must match DebugProbes.usf
# define RENDER_DEPTHPREPASS 0
# define RENDER_BASEPASS 1
# define RENDER_VELOCITYPASS 2
2021-05-26 04:46:16 -04:00
class FStampDeferredDebugProbePS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER ( FStampDeferredDebugProbePS ) ;
SHADER_USE_PARAMETER_STRUCT ( FStampDeferredDebugProbePS , FGlobalShader ) ;
2021-05-31 16:19:28 -04:00
class FRenderPass : SHADER_PERMUTATION_RANGE_INT ( " PERMUTATION_PASS " , 0 , 3 ) ;
2022-07-06 14:43:32 -04:00
class FIlluminanceMeter : SHADER_PERMUTATION_BOOL ( " PERMUTATION_ILLUMINANCEMETER " ) ;
using FPermutationDomain = TShaderPermutationDomain < FRenderPass , FIlluminanceMeter > ;
2021-05-26 04:46:16 -04:00
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
SHADER_PARAMETER_STRUCT_REF ( FViewUniformShaderParameters , ViewUniformBuffer )
2021-11-29 09:31:58 -05:00
SHADER_PARAMETER_RDG_TEXTURE_UAV ( RWTexture2DArray < uint > , MaterialTextureArrayUAV )
2021-05-31 16:19:28 -04:00
SHADER_PARAMETER ( uint32 , MaxBytesPerPixel )
2022-04-13 10:23:39 -04:00
SHADER_PARAMETER ( uint32 , bRoughDiffuse )
2021-06-01 04:03:25 -04:00
SHADER_PARAMETER_STRUCT_INCLUDE ( FSceneTextureShaderParameters , SceneTextures )
2021-05-26 04:46:16 -04:00
SHADER_PARAMETER ( int32 , DebugProbesMode )
RENDER_TARGET_BINDING_SLOTS ( )
END_SHADER_PARAMETER_STRUCT ( )
public :
static FPermutationDomain RemapPermutation ( FPermutationDomain PermutationVector )
{
return PermutationVector ;
}
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters )
{
return IsFeatureLevelSupported ( Parameters . Platform , ERHIFeatureLevel : : SM5 ) & & EnumHasAllFlags ( Parameters . Flags , EShaderPermutationFlags : : HasEditorOnlyData ) ;
}
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
2022-02-22 12:35:58 -05:00
OutEnvironment . SetDefine ( TEXT ( " STRATA_INLINE_SHADING " ) , 1 ) ;
2021-05-26 04:46:16 -04:00
}
} ;
IMPLEMENT_GLOBAL_SHADER ( FStampDeferredDebugProbePS , " /Engine/Private/DebugProbes.usf " , " MainPS " , SF_Pixel ) ;
2022-07-01 05:35:21 -04:00
# if DEBUG_PROBE_ENABLED
2022-07-06 14:43:32 -04:00
static bool ViewRequiresAndSupportsIlluminanceMeter ( const FViewInfo & View )
2022-07-01 05:35:21 -04:00
{
2022-07-06 14:43:32 -04:00
if ( View . Family - > EngineShowFlags . VisualizeHDR // This is the debug view contain the illuminance meter
& & IsIlluminanceMeterSupportedByView ( View ) ) // For instance: forward shading does not work with illuminance meter (we need a material buffer to work with)
2022-07-01 05:35:21 -04:00
{
2022-07-06 14:43:32 -04:00
return true ;
2022-07-01 05:35:21 -04:00
}
return false ;
}
2021-05-26 04:46:16 -04:00
2021-06-01 04:03:25 -04:00
template < bool bEnableDepthWrite , ECompareFunction CompareFunction >
2021-05-26 04:46:16 -04:00
static void CommonStampDeferredDebugProbeDrawCall (
FRDGBuilder & GraphBuilder ,
const FViewInfo & View ,
2021-05-26 06:26:05 -04:00
FStampDeferredDebugProbePS : : FParameters * PassParameters ,
2022-07-01 05:35:21 -04:00
int32 RenderPass ,
2022-07-06 14:43:32 -04:00
bool bIlluminanceMeter )
2021-05-26 04:46:16 -04:00
{
PassParameters - > ViewUniformBuffer = View . ViewUniformBuffer ;
2022-04-02 14:31:01 -04:00
PassParameters - > MaterialTextureArrayUAV = View . StrataViewData . SceneData - > MaterialTextureArrayUAVWithoutRTs ;
PassParameters - > MaxBytesPerPixel = View . StrataViewData . SceneData - > MaxBytesPerPixel ;
2022-04-13 10:23:39 -04:00
PassParameters - > bRoughDiffuse = View . StrataViewData . SceneData - > bRoughDiffuse ? 1 : 0 ;
2021-05-31 08:56:02 -04:00
PassParameters - > DebugProbesMode = View . Family - > EngineShowFlags . VisualizeLightingOnProbes ? 3 : FMath : : Clamp ( CVarVisualizeLightingOnProbes . GetValueOnRenderThread ( ) , 0 , 3 ) ;
2021-05-26 05:42:14 -04:00
2021-05-26 04:46:16 -04:00
FStampDeferredDebugProbePS : : FPermutationDomain PermutationVector ;
2021-05-31 16:19:28 -04:00
PermutationVector . Set < FStampDeferredDebugProbePS : : FRenderPass > ( RenderPass ) ;
2022-07-06 14:43:32 -04:00
PermutationVector . Set < FStampDeferredDebugProbePS : : FIlluminanceMeter > ( bIlluminanceMeter ) ;
2021-05-26 04:46:16 -04:00
TShaderMapRef < FStampDeferredDebugProbePS > PixelShader ( View . ShaderMap , PermutationVector ) ;
FPixelShaderUtils : : AddFullscreenPass < FStampDeferredDebugProbePS > (
GraphBuilder , View . ShaderMap , RDG_EVENT_NAME ( " StampDeferredDebugProbePS " ) ,
PixelShader , PassParameters , View . ViewRect ,
TStaticBlendState < > : : GetRHI ( ) ,
TStaticRasterizerState < FM_Solid , CM_None > : : GetRHI ( ) ,
2021-06-01 04:03:25 -04:00
TStaticDepthStencilState < bEnableDepthWrite , CompareFunction > : : GetRHI ( ) ) ;
2021-05-26 04:46:16 -04:00
}
2022-07-01 05:35:21 -04:00
# endif // DEBUG_PROBE_ENABLED
2021-05-26 04:46:16 -04:00
void StampDeferredDebugProbeDepthPS (
FRDGBuilder & GraphBuilder ,
TArrayView < const FViewInfo > Views ,
const FRDGTextureRef SceneDepthTexture )
{
2022-07-01 05:35:21 -04:00
# if DEBUG_PROBE_ENABLED
2021-05-26 04:46:16 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " StampDeferredDebugProbeDepth " ) ;
RDG_GPU_STAT_SCOPE ( GraphBuilder , StampDeferredDebugProbe ) ;
2021-05-31 08:56:02 -04:00
const bool bVisualizeLightingOnProbes = CVarVisualizeLightingOnProbes . GetValueOnRenderThread ( ) > 0 ;
2021-05-26 04:46:16 -04:00
for ( const FViewInfo & View : Views )
{
2022-07-06 14:43:32 -04:00
const bool bViewRequiresAndSupportsIlluminanceMeter = ViewRequiresAndSupportsIlluminanceMeter ( View ) ;
if ( ! ( bVisualizeLightingOnProbes | | View . Family - > EngineShowFlags . VisualizeLightingOnProbes ) | | View . bIsReflectionCapture | | bViewRequiresAndSupportsIlluminanceMeter )
2021-05-26 05:42:14 -04:00
{
2022-07-06 14:43:32 -04:00
// When "Visualizing HDR with Illuminance Meter", we want to evaluated the illuminance on the surface behind the target square patch.
// So we do not want write depth or velocity in this case.
2021-05-26 05:42:14 -04:00
continue ;
}
2021-05-26 04:46:16 -04:00
FStampDeferredDebugProbePS : : FParameters * PassParameters = GraphBuilder . AllocParameters < FStampDeferredDebugProbePS : : FParameters > ( ) ;
PassParameters - > RenderTargets . DepthStencil = FDepthStencilBinding ( SceneDepthTexture , ERenderTargetLoadAction : : ELoad , ERenderTargetLoadAction : : ELoad , FExclusiveDepthStencil : : DepthWrite_StencilWrite ) ;
2022-07-06 14:43:32 -04:00
CommonStampDeferredDebugProbeDrawCall < true , CF_DepthNearOrEqual > ( GraphBuilder , View , PassParameters , RENDER_DEPTHPREPASS , bViewRequiresAndSupportsIlluminanceMeter ) ;
2021-05-26 04:46:16 -04:00
}
2022-07-01 05:35:21 -04:00
# endif // DEBUG_PROBE_ENABLED
2021-05-26 04:46:16 -04:00
}
void StampDeferredDebugProbeMaterialPS (
FRDGBuilder & GraphBuilder ,
TArrayView < const FViewInfo > Views ,
2021-06-01 04:03:25 -04:00
const FRenderTargetBindingSlots & BasePassRenderTargets ,
const FMinimalSceneTextures & SceneTextures )
2021-05-26 04:46:16 -04:00
{
2022-07-01 05:35:21 -04:00
# if DEBUG_PROBE_ENABLED
2021-05-26 04:46:16 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " StampDeferredDebugProbeMaterial " ) ;
RDG_GPU_STAT_SCOPE ( GraphBuilder , StampDeferredDebugProbe ) ;
2021-05-31 08:56:02 -04:00
const bool bVisualizeLightingOnProbes = CVarVisualizeLightingOnProbes . GetValueOnRenderThread ( ) > 0 ;
2021-05-26 04:46:16 -04:00
for ( const FViewInfo & View : Views )
{
2022-07-06 14:43:32 -04:00
const bool bViewRequiresAndSupportsIlluminanceMeter = ViewRequiresAndSupportsIlluminanceMeter ( View ) ;
if ( ! ( bVisualizeLightingOnProbes | | View . Family - > EngineShowFlags . VisualizeLightingOnProbes | | bViewRequiresAndSupportsIlluminanceMeter ) | | View . bIsReflectionCapture )
2021-05-26 05:42:14 -04:00
{
continue ;
}
2021-05-26 04:46:16 -04:00
FStampDeferredDebugProbePS : : FParameters * PassParameters = GraphBuilder . AllocParameters < FStampDeferredDebugProbePS : : FParameters > ( ) ;
PassParameters - > RenderTargets = BasePassRenderTargets ;
2022-07-06 14:43:32 -04:00
if ( bViewRequiresAndSupportsIlluminanceMeter )
{
// We do not want to update the normal of the material in this case,
// because in this case we want to use the scene normal as the direction of the hemisphere over which we evaluate Illuminance.
// So for legacy, we unbind the normal buffer and for strata we unbind the toplayer data (that is enough since the material written is going to be of simple type)
if ( Strata : : IsStrataEnabled ( ) )
{
// Search for the TopLayerTexture render target and nullify it to not update it.
for ( int32 i = 0 ; i < MaxSimultaneousRenderTargets ; + + i )
{
if ( PassParameters - > RenderTargets . Output [ i ] . GetTexture ( ) = = View . StrataViewData . SceneData - > TopLayerTexture )
{
PassParameters - > RenderTargets . Output [ i ] = FRenderTargetBinding ( ) ;
}
}
}
else
{
// Do not write to the GBuffer normal render target, use a dummy render target to avoid validation issue with target textures that must be packed.
PassParameters - > RenderTargets . Output [ 1 ] = FRenderTargetBinding ( GraphBuilder . CreateTexture ( PassParameters - > RenderTargets . Output [ 1 ] . GetTexture ( ) - > Desc , TEXT ( " DummyGBufferNormalTexture " ) ) , ERenderTargetLoadAction : : ELoad ) ;
}
}
2021-06-01 04:03:25 -04:00
if ( Strata : : IsStrataEnabled ( ) )
{
// Make sure we do not write depth so that we can safely read it from texture parameters
PassParameters - > RenderTargets . DepthStencil = FDepthStencilBinding ( ) ;
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
PassParameters - > SceneTextures = CreateSceneTextureShaderParameters ( GraphBuilder , View . GetSceneTexturesChecked ( ) , View . GetFeatureLevel ( ) , ESceneTextureSetupMode : : SceneDepth ) ;
2021-06-01 04:03:25 -04:00
2022-07-06 14:43:32 -04:00
CommonStampDeferredDebugProbeDrawCall < false , CF_Always > ( GraphBuilder , View , PassParameters , RENDER_BASEPASS , bViewRequiresAndSupportsIlluminanceMeter ) ;
2021-06-01 04:03:25 -04:00
}
else
{
2022-07-06 14:43:32 -04:00
CommonStampDeferredDebugProbeDrawCall < false , CF_DepthNearOrEqual > ( GraphBuilder , View , PassParameters , RENDER_BASEPASS , bViewRequiresAndSupportsIlluminanceMeter ) ;
2021-06-01 04:03:25 -04:00
}
2021-05-26 04:46:16 -04:00
}
2022-07-01 05:35:21 -04:00
# endif // DEBUG_PROBE_ENABLED
2021-05-26 04:46:16 -04:00
}
2021-05-26 06:26:05 -04:00
void StampDeferredDebugProbeVelocityPS (
FRDGBuilder & GraphBuilder ,
TArrayView < const FViewInfo > Views ,
const FRenderTargetBindingSlots & BasePassRenderTargets )
{
2022-07-01 05:35:21 -04:00
# if DEBUG_PROBE_ENABLED
2021-05-26 06:26:05 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " StampDeferredDebugProbeVelocity " ) ;
RDG_GPU_STAT_SCOPE ( GraphBuilder , StampDeferredDebugProbe ) ;
2021-05-31 08:56:02 -04:00
const bool bVisualizeLightingOnProbes = CVarVisualizeLightingOnProbes . GetValueOnRenderThread ( ) > 0 ;
2021-05-26 06:26:05 -04:00
for ( const FViewInfo & View : Views )
{
2022-07-06 14:43:32 -04:00
const bool bViewRequiresAndSupportsIlluminanceMeter = ViewRequiresAndSupportsIlluminanceMeter ( View ) ;
if ( ! ( bVisualizeLightingOnProbes | | View . Family - > EngineShowFlags . VisualizeLightingOnProbes ) | | View . bIsReflectionCapture | | bViewRequiresAndSupportsIlluminanceMeter )
2021-05-26 06:26:05 -04:00
{
2022-07-06 14:43:32 -04:00
// When "Visualizing HDR with Illuminance Meter", we want to evaluated the illuminance on the surface behind the target square patch.
// So we do not want write depth or velocity in this case.
2021-05-26 06:26:05 -04:00
continue ;
}
FStampDeferredDebugProbePS : : FParameters * PassParameters = GraphBuilder . AllocParameters < FStampDeferredDebugProbePS : : FParameters > ( ) ;
PassParameters - > RenderTargets = BasePassRenderTargets ;
const bool bRenderVelocity = true ;
2022-07-06 14:43:32 -04:00
CommonStampDeferredDebugProbeDrawCall < false , CF_DepthNearOrEqual > ( GraphBuilder , View , PassParameters , RENDER_VELOCITYPASS , bViewRequiresAndSupportsIlluminanceMeter ) ;
2021-05-26 06:26:05 -04:00
}
2022-07-01 05:35:21 -04:00
# endif // DEBUG_PROBE_ENABLED
2021-05-26 06:26:05 -04:00
}