// Copyright Epic Games, Inc. All Rights Reserved. #include "LumenScreenProbeGather.h" #include "RendererPrivate.h" #include "ScenePrivate.h" #include "SceneUtils.h" #include "PipelineStateCache.h" #include "ShaderParameterStruct.h" #include "PixelShaderUtils.h" #include "ReflectionEnvironment.h" #include "DistanceFieldAmbientOcclusion.h" #include "HairStrands/HairStrandsData.h" int32 GLumenScreenProbeGatherScreenTraces = 1; FAutoConsoleVariableRef GVarLumenScreenProbeGatherScreenTraces( TEXT("r.Lumen.ScreenProbeGather.ScreenTraces"), GLumenScreenProbeGatherScreenTraces, TEXT("Whether to trace against the screen before falling back to other tracing methods."), ECVF_Scalability | ECVF_RenderThreadSafe ); static TAutoConsoleVariable CVarLumenScreenProbeGatherScreenTracesHairBias( TEXT("r.Lumen.ScreenProbeGather.ScreenTraces.HairBias"), 2.0f, TEXT("Bias for screen space rays traced from hair pixels. Usually hair has pretty complex geometry and requires a special bias value."), ECVF_RenderThreadSafe ); int32 GLumenScreenProbeGatherHierarchicalScreenTraces = 1; FAutoConsoleVariableRef GVarLumenScreenProbeGatherHierarchicalScreenTraces( TEXT("r.Lumen.ScreenProbeGather.ScreenTraces.HZBTraversal"), GLumenScreenProbeGatherHierarchicalScreenTraces, TEXT("Whether to use HZB tracing for SSGI instead of fixed step count intersection. HZB tracing is much more accurate, in particular not missing thin features, but is about ~3x slower."), ECVF_Scalability | ECVF_RenderThreadSafe ); int32 GLumenScreenProbeGatherHierarchicalScreenTracesFullResDepth = 1; FAutoConsoleVariableRef GVarLumenScreenProbeGatherHierarchicalScreenTracesFullResDepth( TEXT("r.Lumen.ScreenProbeGather.ScreenTraces.HZBTraversal.FullResDepth"), GLumenScreenProbeGatherHierarchicalScreenTracesFullResDepth, TEXT("Whether the HZB traversal should go all the way down to the full resolution depth, which is more accurate but adds incoherency to the inner loop."), ECVF_Scalability | ECVF_RenderThreadSafe ); int32 GLumenScreenProbeGatherHierarchicalScreenTracesSkipFoliageHits = 1; FAutoConsoleVariableRef GVarLumenScreenProbeGatherHierarchicalScreenTracesSkipFoliageHits( TEXT("r.Lumen.ScreenProbeGather.ScreenTraces.HZBTraversal.SkipFoliageHits"), GLumenScreenProbeGatherHierarchicalScreenTracesSkipFoliageHits, TEXT("Whether to allow screen traces to hit Subsurface and TwoSided Foliage shading models. Can be used to work around aliasing from high frequency grass geometry."), ECVF_Scalability | ECVF_RenderThreadSafe ); static TAutoConsoleVariable GVarLumenScreenProbeGatherHierarchicalScreenTracesSkipHairHits( TEXT("r.Lumen.ScreenProbeGather.ScreenTraces.HZBTraversal.SkipHairHits"), 0, TEXT("Whether to allow screen traces to hit hair shading models. Can be used to work around aliasing from high frequency hair cards geometry."), ECVF_Scalability | ECVF_RenderThreadSafe ); int32 GLumenScreenProbeGatherHierarchicalScreenTracesMaxIterations = 50; FAutoConsoleVariableRef GVarLumenScreenProbeGatherHierarchicalScreenTracesMaxIterations( TEXT("r.Lumen.ScreenProbeGather.ScreenTraces.HZBTraversal.MaxIterations"), GLumenScreenProbeGatherHierarchicalScreenTracesMaxIterations, TEXT("Max iterations for HZB tracing."), ECVF_Scalability | ECVF_RenderThreadSafe ); float GLumenScreenProbeGatherRelativeDepthThickness = .02f; FAutoConsoleVariableRef GVarLumenScreenProbeGatherRelativeDepthThickness( TEXT("r.Lumen.ScreenProbeGather.ScreenTraces.HZBTraversal.RelativeDepthThickness"), GLumenScreenProbeGatherRelativeDepthThickness, TEXT("Determines depth thickness of objects hit by HZB tracing, as a relative depth threshold."), ECVF_Scalability | ECVF_RenderThreadSafe ); float GLumenScreenProbeGatherHistoryDepthTestRelativeThickness = 0.005f; FAutoConsoleVariableRef GVarLumenScreenProbeGatherHistoryDepthTestRelativeThickness( TEXT("r.Lumen.ScreenProbeGather.ScreenTraces.HZBTraversal.HistoryDepthTestRelativeThickness"), GLumenScreenProbeGatherHistoryDepthTestRelativeThickness, TEXT("Distance between HZB trace hit and previous frame scene depth from which to allow hits, as a relative depth threshold."), ECVF_Scalability | ECVF_RenderThreadSafe ); int32 GLumenScreenProbeGatherNumThicknessStepsToDetermineCertainty = 4; FAutoConsoleVariableRef GVarLumenScreenProbeGatherNumThicknessStepsToDetermineCertainty( TEXT("r.Lumen.ScreenProbeGather.ScreenTraces.HZBTraversal.NumThicknessStepsToDetermineCertainty"), GLumenScreenProbeGatherNumThicknessStepsToDetermineCertainty, TEXT("Number of linear search steps to determine if a hit feature is thin and should be ignored."), ECVF_Scalability | ECVF_RenderThreadSafe ); int32 GLumenScreenProbeGatherVisualizeTraces = 0; FAutoConsoleVariableRef GVarLumenScreenProbeGatherVisualizeTraces( TEXT("r.Lumen.ScreenProbeGather.VisualizeTraces"), GLumenScreenProbeGatherVisualizeTraces, TEXT("Whether to visualize traces for the center screen probe, useful for debugging"), ECVF_Scalability | ECVF_RenderThreadSafe ); int32 GLumenScreenProbeGatherVisualizeTracesFreeze = 0; FAutoConsoleVariableRef GVarLumenScreenProbeGatherVisualizeTracesFreeze( TEXT("r.Lumen.ScreenProbeGather.VisualizeTracesFreeze"), GLumenScreenProbeGatherVisualizeTracesFreeze, TEXT("Whether to freeze updating the visualize trace data. Note that no changes to cvars or shaders will propagate until unfrozen."), ECVF_Scalability | ECVF_RenderThreadSafe ); int32 GLumenScreenProbeGatherHairStrands_VoxelTrace = 1; FAutoConsoleVariableRef GVarLumenScreenProbeGatherHairStrands_VoxelTrace( TEXT("r.Lumen.ScreenProbeGather.HairStrands.VoxelTrace"), GLumenScreenProbeGatherHairStrands_VoxelTrace, TEXT("Whether to trace against hair voxel structure for hair casting shadow onto opaques."), ECVF_Scalability | ECVF_RenderThreadSafe ); int32 GLumenScreenProbeGatherHairStrands_ScreenTrace = 0; FAutoConsoleVariableRef GVarLumenScreenProbeGatherHairStrands_ScreenTrace( TEXT("r.Lumen.ScreenProbeGather.HairStrands.ScreenTrace"), GLumenScreenProbeGatherHairStrands_ScreenTrace, TEXT("Whether to trace against hair depth for hair casting shadow onto opaques."), ECVF_Scalability | ECVF_RenderThreadSafe ); int32 GLumenScreenProbeGatherScreenTracesMinimumOccupancy = 0; FAutoConsoleVariableRef CVarLumenScreenProbeGatherScreenTraceMinimumOccupancy( TEXT("r.Lumen.ScreenProbeGather.ScreenTraces.MinimumOccupancy"), GLumenScreenProbeGatherScreenTracesMinimumOccupancy, TEXT("Minimum number of threads still tracing before aborting the trace. Can be used for scalability to abandon traces that have a disproportionate cost."), ECVF_Scalability | ECVF_RenderThreadSafe ); bool SupportsHairScreenTraces() { return GVarLumenScreenProbeGatherHierarchicalScreenTracesSkipHairHits.GetValueOnRenderThread() == 0; } class FClearTracesCS : public FGlobalShader { DECLARE_GLOBAL_SHADER(FClearTracesCS) SHADER_USE_PARAMETER_STRUCT(FClearTracesCS, FGlobalShader) BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) SHADER_PARAMETER_STRUCT_INCLUDE(FScreenProbeParameters, ScreenProbeParameters) END_SHADER_PARAMETER_STRUCT() static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) { return DoesPlatformSupportLumenGI(Parameters.Platform); } static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) { FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); } }; IMPLEMENT_GLOBAL_SHADER(FClearTracesCS, "/Engine/Private/Lumen/LumenScreenProbeTracing.usf", "ClearTracesCS", SF_Compute); class FScreenProbeTraceScreenTexturesCS : public FGlobalShader { DECLARE_GLOBAL_SHADER(FScreenProbeTraceScreenTexturesCS) SHADER_USE_PARAMETER_STRUCT(FScreenProbeTraceScreenTexturesCS, FGlobalShader) BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) SHADER_PARAMETER_STRUCT_INCLUDE(FLumenCardTracingParameters, TracingParameters) SHADER_PARAMETER_STRUCT_INCLUDE(FLumenHZBScreenTraceParameters, HZBScreenTraceParameters) SHADER_PARAMETER_STRUCT_INCLUDE(FSceneTextureParameters, SceneTextures) SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FSubstrateGlobalUniformParameters, Substrate) SHADER_PARAMETER_RDG_TEXTURE(Texture2D, LightingChannelsTexture) SHADER_PARAMETER(uint32, ScreenProbeGatherStateFrameIndex) SHADER_PARAMETER(float, MaxHierarchicalScreenTraceIterations) SHADER_PARAMETER(float, RelativeDepthThickness) SHADER_PARAMETER(float, HistoryDepthTestRelativeThickness) SHADER_PARAMETER(float, NumThicknessStepsToDetermineCertainty) SHADER_PARAMETER(float, BiasForTracesFromHairPixels) SHADER_PARAMETER(uint32, MinimumTracingThreadOccupancy) SHADER_PARAMETER(uint32, SkipFoliageHits) SHADER_PARAMETER(uint32, SkipHairHits) SHADER_PARAMETER_STRUCT_INCLUDE(FScreenProbeParameters, ScreenProbeParameters) SHADER_PARAMETER_STRUCT_INCLUDE(FLumenIndirectTracingParameters, IndirectTracingParameters) SHADER_PARAMETER_STRUCT_INCLUDE(LumenRadianceCache::FRadianceCacheInterpolationParameters, RadianceCacheParameters) SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FHairStrandsViewUniformParameters, HairStrands) END_SHADER_PARAMETER_STRUCT() class FRadianceCache : SHADER_PERMUTATION_BOOL("RADIANCE_CACHE"); class FHierarchicalScreenTracing : SHADER_PERMUTATION_BOOL("HIERARCHICAL_SCREEN_TRACING"); class FTraceFullResDepth : SHADER_PERMUTATION_BOOL("HZB_TRACE_INCLUDE_FULL_RES_DEPTH"); class FStructuredImportanceSampling : SHADER_PERMUTATION_BOOL("STRUCTURED_IMPORTANCE_SAMPLING"); class FHairStrands : SHADER_PERMUTATION_BOOL("USE_HAIRSTRANDS_SCREEN"); class FTerminateOnLowOccupancy : SHADER_PERMUTATION_BOOL("TERMINATE_ON_LOW_OCCUPANCY"); class FUseDistanceFieldRepresentationBit : SHADER_PERMUTATION_BOOL("USE_DISTANCE_FIELD_REPRESENTATION_BIT"); using FPermutationDomain = TShaderPermutationDomain; static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) { FPermutationDomain PermutationVector(Parameters.PermutationId); if (PermutationVector.Get() && !RHISupportsWaveOperations(Parameters.Platform)) { return false; } if (PermutationVector.Get() && !PermutationVector.Get()) { return false; } return DoesPlatformSupportLumenGI(Parameters.Platform); } static EShaderPermutationPrecacheRequest ShouldPrecachePermutation(const FGlobalShaderPermutationParameters& Parameters) { FPermutationDomain PermutationVector(Parameters.PermutationId); const bool bTerminateOnLowOccupancy = GLumenScreenProbeGatherScreenTracesMinimumOccupancy > 0 && GRHISupportsWaveOperations && GRHIMinimumWaveSize <= 32 && GRHIMaximumWaveSize >= 32 && RHISupportsWaveOperations(Parameters.Platform); const bool bHZBTraversal = GLumenScreenProbeGatherHierarchicalScreenTraces != 0; if (PermutationVector.Get() != LumenScreenProbeGather::UseRadianceCache()) { return EShaderPermutationPrecacheRequest::NotUsed; } if (PermutationVector.Get() != bHZBTraversal) { return EShaderPermutationPrecacheRequest::NotUsed; } if (PermutationVector.Get() != (bHZBTraversal && GLumenScreenProbeGatherHierarchicalScreenTracesFullResDepth != 0)) { return EShaderPermutationPrecacheRequest::NotUsed; } return EShaderPermutationPrecacheRequest::Precached; } static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) { FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); OutEnvironment.CompilerFlags.Add(CFLAG_Wave32); FPermutationDomain PermutationVector(Parameters.PermutationId); if (PermutationVector.Get()) { OutEnvironment.CompilerFlags.Add(CFLAG_WaveOperations); } } }; IMPLEMENT_GLOBAL_SHADER(FScreenProbeTraceScreenTexturesCS, "/Engine/Private/Lumen/LumenScreenProbeTracing.usf", "ScreenProbeTraceScreenTexturesCS", SF_Compute); class FScreenProbeCompactTracesCS : public FGlobalShader { DECLARE_GLOBAL_SHADER(FScreenProbeCompactTracesCS) SHADER_USE_PARAMETER_STRUCT(FScreenProbeCompactTracesCS, FGlobalShader) BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, ViewUniformBuffer) SHADER_PARAMETER_STRUCT_INCLUDE(FScreenProbeParameters, ScreenProbeParameters) SHADER_PARAMETER(uint32, CullByDistanceFromCamera) SHADER_PARAMETER(float, CompactionTracingEndDistanceFromCamera) SHADER_PARAMETER(float, CompactionMaxTraceDistance) SHADER_PARAMETER(uint32, CompactForSkyApply) SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer, RWCompactedTraceTexelAllocator) SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer, RWCompactedTraceTexelData) END_SHADER_PARAMETER_STRUCT() static int32 GetGroupSize() { return 16; } class FWaveOps : SHADER_PERMUTATION_BOOL("WAVE_OPS"); using FPermutationDomain = TShaderPermutationDomain; static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) { FPermutationDomain PermutationVector(Parameters.PermutationId); if (PermutationVector.Get() && !RHISupportsWaveOperations(Parameters.Platform)) { return false; } return DoesPlatformSupportLumenGI(Parameters.Platform); } static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) { FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE"), GetGroupSize()); FPermutationDomain PermutationVector(Parameters.PermutationId); if (PermutationVector.Get()) { OutEnvironment.CompilerFlags.Add(CFLAG_WaveOperations); } } }; IMPLEMENT_GLOBAL_SHADER(FScreenProbeCompactTracesCS, "/Engine/Private/Lumen/LumenScreenProbeTracing.usf", "ScreenProbeCompactTracesCS", SF_Compute); class FSetupCompactedTracesIndirectArgsCS : public FGlobalShader { DECLARE_GLOBAL_SHADER(FSetupCompactedTracesIndirectArgsCS) SHADER_USE_PARAMETER_STRUCT(FSetupCompactedTracesIndirectArgsCS, FGlobalShader) BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer, RWScreenProbeCompactTracingIndirectArgs) SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer, CompactedTraceTexelAllocator) SHADER_PARAMETER_STRUCT_INCLUDE(FScreenProbeParameters, ScreenProbeParameters) END_SHADER_PARAMETER_STRUCT() static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) { return DoesPlatformSupportLumenGI(Parameters.Platform); } }; IMPLEMENT_GLOBAL_SHADER(FSetupCompactedTracesIndirectArgsCS, "/Engine/Private/Lumen/LumenScreenProbeTracing.usf", "SetupCompactedTracesIndirectArgsCS", SF_Compute); class FScreenProbeTraceMeshSDFsCS : public FGlobalShader { DECLARE_GLOBAL_SHADER(FScreenProbeTraceMeshSDFsCS) SHADER_USE_PARAMETER_STRUCT(FScreenProbeTraceMeshSDFsCS, FGlobalShader) BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) SHADER_PARAMETER_STRUCT_INCLUDE(FLumenCardTracingParameters, TracingParameters) SHADER_PARAMETER_STRUCT_INCLUDE(FLumenMeshSDFGridParameters, MeshSDFGridParameters) SHADER_PARAMETER_STRUCT_INCLUDE(FScreenProbeParameters, ScreenProbeParameters) SHADER_PARAMETER_STRUCT_INCLUDE(FLumenIndirectTracingParameters, IndirectTracingParameters) SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FSceneTextureUniformParameters, SceneTexturesStruct) SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FVirtualVoxelParameters, HairStrandsVoxel) SHADER_PARAMETER_STRUCT_INCLUDE(FCompactedTraceParameters, CompactedTraceParameters) END_SHADER_PARAMETER_STRUCT() class FThreadGroupSize32 : SHADER_PERMUTATION_BOOL("THREADGROUP_SIZE_32"); class FStructuredImportanceSampling : SHADER_PERMUTATION_BOOL("STRUCTURED_IMPORTANCE_SAMPLING"); class FHairStrands : SHADER_PERMUTATION_BOOL("USE_HAIRSTRANDS_VOXEL"); class FTraceMeshSDFs : SHADER_PERMUTATION_BOOL("SCENE_TRACE_MESH_SDFS"); class FTraceHeightfields : SHADER_PERMUTATION_BOOL("SCENE_TRACE_HEIGHTFIELDS"); class FOffsetDataStructure : SHADER_PERMUTATION_INT("OFFSET_DATA_STRUCT", 3); using FPermutationDomain = TShaderPermutationDomain; static FPermutationDomain RemapPermutation(FPermutationDomain PermutationVector) { // FOffsetDataStructure is only used for mesh SDFs if (!PermutationVector.Get()) { PermutationVector.Set(0); } return PermutationVector; } static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) { FPermutationDomain PermutationVector(Parameters.PermutationId); if (RemapPermutation(PermutationVector) != PermutationVector) { return false; } return DoesPlatformSupportLumenGI(Parameters.Platform); } static EShaderPermutationPrecacheRequest ShouldPrecachePermutation(const FGlobalShaderPermutationParameters& Parameters) { FPermutationDomain PermutationVector = RemapPermutation(FPermutationDomain(Parameters.PermutationId)); extern int32 GDistanceFieldOffsetDataStructure; if (PermutationVector.Get() != GDistanceFieldOffsetDataStructure) { return EShaderPermutationPrecacheRequest::NotUsed; } if (PermutationVector.Get() != Lumen::UseThreadGroupSize32()) { return EShaderPermutationPrecacheRequest::NotUsed; } return EShaderPermutationPrecacheRequest::Precached; } static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) { FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); OutEnvironment.SetDefine(TEXT("VF_SUPPORTS_PRIMITIVE_SCENE_DATA"), 1); OutEnvironment.CompilerFlags.Add(CFLAG_Wave32); } }; IMPLEMENT_GLOBAL_SHADER(FScreenProbeTraceMeshSDFsCS, "/Engine/Private/Lumen/LumenScreenProbeTracing.usf", "ScreenProbeTraceMeshSDFsCS", SF_Compute); class FScreenProbeTraceVoxelsCS : public FGlobalShader { DECLARE_GLOBAL_SHADER(FScreenProbeTraceVoxelsCS) SHADER_USE_PARAMETER_STRUCT(FScreenProbeTraceVoxelsCS, FGlobalShader) BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) SHADER_PARAMETER_STRUCT_INCLUDE(FLumenCardTracingParameters, TracingParameters) SHADER_PARAMETER_STRUCT_INCLUDE(FScreenProbeParameters, ScreenProbeParameters) SHADER_PARAMETER_STRUCT_INCLUDE(FLumenIndirectTracingParameters, IndirectTracingParameters) SHADER_PARAMETER_STRUCT_INCLUDE(LumenRadianceCache::FRadianceCacheInterpolationParameters, RadianceCacheParameters) SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FSceneTextureUniformParameters, SceneTexturesStruct) SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FVirtualVoxelParameters, HairStrandsVoxel) SHADER_PARAMETER_STRUCT_INCLUDE(FCompactedTraceParameters, CompactedTraceParameters) END_SHADER_PARAMETER_STRUCT() class FThreadGroupSize32 : SHADER_PERMUTATION_BOOL("THREADGROUP_SIZE_32"); class FRadianceCache : SHADER_PERMUTATION_BOOL("RADIANCE_CACHE"); class FScreenProbeExtraAO : SHADER_PERMUTATION_BOOL("SCREEN_PROBE_EXTRA_AO"); class FStructuredImportanceSampling : SHADER_PERMUTATION_BOOL("STRUCTURED_IMPORTANCE_SAMPLING"); class FHairStrands : SHADER_PERMUTATION_BOOL("USE_HAIRSTRANDS_VOXEL"); class FTraceVoxels : SHADER_PERMUTATION_BOOL("TRACE_VOXELS"); class FSimpleCoverageBasedExpand : SHADER_PERMUTATION_BOOL("GLOBALSDF_SIMPLE_COVERAGE_BASED_EXPAND"); using FPermutationDomain = TShaderPermutationDomain; static FPermutationDomain RemapPermutation(FPermutationDomain PermutationVector) { if (!PermutationVector.Get()) { PermutationVector.Set(false); } return PermutationVector; } static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) { FPermutationDomain PermutationVector(Parameters.PermutationId); if (RemapPermutation(PermutationVector) != PermutationVector) { return false; } return DoesPlatformSupportLumenGI(Parameters.Platform); } static EShaderPermutationPrecacheRequest ShouldPrecachePermutation(const FGlobalShaderPermutationParameters& Parameters) { FPermutationDomain PermutationVector(Parameters.PermutationId); if (PermutationVector.Get() != Lumen::UseThreadGroupSize32()) { return EShaderPermutationPrecacheRequest::NotUsed; } return EShaderPermutationPrecacheRequest::Precached; } static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) { FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); OutEnvironment.CompilerFlags.Add(CFLAG_Wave32); // Workaround for an internal PC FXC compiler crash when compiling with disabled optimizations if (Parameters.Platform == SP_PCD3D_SM5) { OutEnvironment.CompilerFlags.Add(CFLAG_ForceOptimization); } } }; IMPLEMENT_GLOBAL_SHADER(FScreenProbeTraceVoxelsCS, "/Engine/Private/Lumen/LumenScreenProbeTracing.usf", "ScreenProbeTraceVoxelsCS", SF_Compute); class FScreenProbeSetupVisualizeTracesCS : public FGlobalShader { DECLARE_GLOBAL_SHADER(FScreenProbeSetupVisualizeTracesCS) SHADER_USE_PARAMETER_STRUCT(FScreenProbeSetupVisualizeTracesCS, FGlobalShader) BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer, RWVisualizeTracesData) SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, View) SHADER_PARAMETER_STRUCT_INCLUDE(FScreenProbeParameters, ScreenProbeParameters) SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FSceneTextureUniformParameters, SceneTexturesStruct) END_SHADER_PARAMETER_STRUCT() class FStructuredImportanceSampling : SHADER_PERMUTATION_BOOL("STRUCTURED_IMPORTANCE_SAMPLING"); using FPermutationDomain = TShaderPermutationDomain; static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) { return DoesPlatformSupportLumenGI(Parameters.Platform); } static int32 GetGroupSize() { return 8; } static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) { FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE"), GetGroupSize()); } }; IMPLEMENT_GLOBAL_SHADER(FScreenProbeSetupVisualizeTracesCS, "/Engine/Private/Lumen/LumenScreenProbeTracing.usf", "ScreenProbeSetupVisualizeTraces", SF_Compute); TRefCountPtr GVisualizeTracesData; void SetupVisualizeTraces( FRDGBuilder& GraphBuilder, const FSceneTextures& SceneTextures, const FScene* Scene, const FViewInfo& View, const FScreenProbeParameters& ScreenProbeParameters, ERDGPassFlags ComputePassFlags) { FRDGBufferRef VisualizeTracesData = nullptr; if (GVisualizeTracesData.IsValid()) { VisualizeTracesData = GraphBuilder.RegisterExternalBuffer(GVisualizeTracesData); } const int32 VisualizeBufferNumElements = ScreenProbeParameters.ScreenProbeTracingOctahedronResolution * ScreenProbeParameters.ScreenProbeTracingOctahedronResolution * 3; bool bShouldUpdate = !GLumenScreenProbeGatherVisualizeTracesFreeze; if (!VisualizeTracesData || VisualizeTracesData->Desc.NumElements != VisualizeBufferNumElements) { VisualizeTracesData = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateBufferDesc(sizeof(FVector4f), VisualizeBufferNumElements), TEXT("VisualizeTracesData")); bShouldUpdate = true; } if (bShouldUpdate) { FScreenProbeSetupVisualizeTracesCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); PassParameters->View = View.ViewUniformBuffer; PassParameters->ScreenProbeParameters = ScreenProbeParameters; PassParameters->RWVisualizeTracesData = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(VisualizeTracesData, PF_A32B32G32R32F)); PassParameters->SceneTexturesStruct = SceneTextures.UniformBuffer; FScreenProbeSetupVisualizeTracesCS::FPermutationDomain PermutationVector; PermutationVector.Set< FScreenProbeSetupVisualizeTracesCS::FStructuredImportanceSampling >(LumenScreenProbeGather::UseImportanceSampling(View)); auto ComputeShader = View.ShaderMap->GetShader(PermutationVector); FComputeShaderUtils::AddPass( GraphBuilder, RDG_EVENT_NAME("SetupVisualizeTraces"), ComputePassFlags, ComputeShader, PassParameters, FComputeShaderUtils::GetGroupCount(FIntPoint(ScreenProbeParameters.ScreenProbeTracingOctahedronResolution), FScreenProbeSetupVisualizeTracesCS::GetGroupSize())); GVisualizeTracesData = GraphBuilder.ConvertToExternalBuffer(VisualizeTracesData); } } void GetScreenProbeVisualizeTracesBuffer(TRefCountPtr& VisualizeTracesData) { if (GLumenScreenProbeGatherVisualizeTraces && GVisualizeTracesData.IsValid()) { VisualizeTracesData = GVisualizeTracesData; } } enum class ECompactedTracingIndirectArgs { NumTracesDiv64 = 0 * sizeof(FRHIDispatchIndirectParameters), NumTracesDiv32 = 1 * sizeof(FRHIDispatchIndirectParameters), NumLightSampleTracesDiv64 = 2 * sizeof(FRHIDispatchIndirectParameters), NumLightSampleTracesDiv32 = 3 * sizeof(FRHIDispatchIndirectParameters), MAX = 4, }; FCompactedTraceParameters LumenScreenProbeGather::CompactTraces( FRDGBuilder& GraphBuilder, const FViewInfo& View, const FScreenProbeParameters& ScreenProbeParameters, bool bCullByDistanceFromCamera, float CompactionTracingEndDistanceFromCamera, float CompactionMaxTraceDistance, bool bCompactForSkyApply, ERDGPassFlags ComputePassFlags) { FRDGBufferRef CompactedTraceTexelAllocator = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), 1), TEXT("Lumen.ScreenProbeGather.CompactedTraceTexelAllocator")); FRDGBufferUAVRef CompactedTraceTexelAllocatorUAV = GraphBuilder.CreateUAV(CompactedTraceTexelAllocator, PF_R32_UINT, ERDGUnorderedAccessViewFlags::SkipBarrier); AddClearUAVPass(GraphBuilder, GraphBuilder.CreateUAV(CompactedTraceTexelAllocator, PF_R32_UINT), 0, ComputePassFlags); const FIntPoint ScreenProbeTraceBufferSize = ScreenProbeParameters.ScreenProbeAtlasBufferSize * ScreenProbeParameters.ScreenProbeTracingOctahedronResolution; const int32 NumCompactedTraceTexelDataElements = ScreenProbeTraceBufferSize.X * ScreenProbeTraceBufferSize.Y; FRDGBufferRef CompactedTraceTexelData = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), NumCompactedTraceTexelDataElements), TEXT("Lumen.ScreenProbeGather.CompactedTraceTexelData")); { FScreenProbeCompactTracesCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); PassParameters->ViewUniformBuffer = View.ViewUniformBuffer; PassParameters->ScreenProbeParameters = ScreenProbeParameters; PassParameters->RWCompactedTraceTexelAllocator = CompactedTraceTexelAllocatorUAV; PassParameters->RWCompactedTraceTexelData = GraphBuilder.CreateUAV(CompactedTraceTexelData, PF_R32_UINT); PassParameters->CullByDistanceFromCamera = bCullByDistanceFromCamera ? 1 : 0; PassParameters->CompactionTracingEndDistanceFromCamera = CompactionTracingEndDistanceFromCamera; PassParameters->CompactionMaxTraceDistance = CompactionMaxTraceDistance; PassParameters->CompactForSkyApply = bCompactForSkyApply ? 1 : 0; const bool bWaveOps = Lumen::UseWaveOps(View.GetShaderPlatform()) && GRHIMinimumWaveSize <= 32 && GRHIMaximumWaveSize >= 32; FScreenProbeCompactTracesCS::FPermutationDomain PermutationVector; PermutationVector.Set(bWaveOps); auto ComputeShader = View.ShaderMap->GetShader(PermutationVector); FComputeShaderUtils::AddPass( GraphBuilder, RDG_EVENT_NAME("CompactTraces WaveOps:%d", bWaveOps), ComputePassFlags, ComputeShader, PassParameters, ScreenProbeParameters.ProbeIndirectArgs, (uint32)EScreenProbeIndirectArgs::TraceCompaction * sizeof(FRHIDispatchIndirectParameters)); } FCompactedTraceParameters CompactedTraceParameters; CompactedTraceParameters.IndirectArgs = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateIndirectDesc((int32)ECompactedTracingIndirectArgs::MAX), TEXT("Lumen.ScreenProbeGather.CompactTracingIndirectArgs")); { FSetupCompactedTracesIndirectArgsCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); PassParameters->ScreenProbeParameters = ScreenProbeParameters; PassParameters->RWScreenProbeCompactTracingIndirectArgs = GraphBuilder.CreateUAV(CompactedTraceParameters.IndirectArgs, PF_R32_UINT); PassParameters->CompactedTraceTexelAllocator = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(CompactedTraceTexelAllocator, PF_R32_UINT)); auto ComputeShader = View.ShaderMap->GetShader(0); FComputeShaderUtils::AddPass( GraphBuilder, RDG_EVENT_NAME("SetupCompactedTracesIndirectArgs"), ComputePassFlags, ComputeShader, PassParameters, FIntVector(1, 1, 1)); } CompactedTraceParameters.CompactedTraceTexelAllocator = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(CompactedTraceTexelAllocator, PF_R32_UINT)); CompactedTraceParameters.CompactedTraceTexelData = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(CompactedTraceTexelData, PF_R32_UINT)); return CompactedTraceParameters; } void TraceScreenProbes( FRDGBuilder& GraphBuilder, const FScene* Scene, const FViewInfo& View, const FLumenSceneFrameTemporaries& FrameTemporaries, bool bTraceMeshObjects, const FSceneTextures& SceneTextures, FRDGTextureRef LightingChannelsTexture, const LumenRadianceCache::FRadianceCacheInterpolationParameters& RadianceCacheParameters, FScreenProbeParameters& ScreenProbeParameters, FLumenMeshSDFGridParameters& MeshSDFGridParameters, ERDGPassFlags ComputePassFlags) { const FSceneTextureParameters& SceneTextureParameters = GetSceneTextureParameters(GraphBuilder, SceneTextures); { FClearTracesCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); PassParameters->ScreenProbeParameters = ScreenProbeParameters; auto ComputeShader = View.ShaderMap->GetShader(0); FComputeShaderUtils::AddPass( GraphBuilder, RDG_EVENT_NAME("ClearTraces %ux%u", ScreenProbeParameters.ScreenProbeTracingOctahedronResolution, ScreenProbeParameters.ScreenProbeTracingOctahedronResolution), ComputePassFlags, ComputeShader, PassParameters, ScreenProbeParameters.ProbeIndirectArgs, (uint32)EScreenProbeIndirectArgs::ThreadPerTrace * sizeof(FRHIDispatchIndirectParameters)); } FLumenCardTracingParameters TracingParameters; GetLumenCardTracingParameters(GraphBuilder, View, *Scene->GetLumenSceneData(View), FrameTemporaries, /*bSurfaceCacheFeedback*/ false, TracingParameters); FLumenIndirectTracingParameters IndirectTracingParameters; SetupLumenDiffuseTracingParameters(View, IndirectTracingParameters); extern int32 GLumenVisualizeIndirectDiffuse; const bool bTraceScreen = View.PrevViewInfo.ScreenSpaceRayTracingInput.IsValid() && GLumenScreenProbeGatherScreenTraces != 0 && GLumenVisualizeIndirectDiffuse == 0 && View.Family->EngineShowFlags.LumenScreenTraces && View.FinalPostProcessSettings.LumenFinalGatherScreenTraces; if (bTraceScreen) { auto TraceScreen = [&]() { FScreenProbeTraceScreenTexturesCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); PassParameters->HZBScreenTraceParameters = SetupHZBScreenTraceParameters(GraphBuilder, View, SceneTextures); PassParameters->TracingParameters = TracingParameters; PassParameters->SceneTextures = SceneTextureParameters; if (PassParameters->HZBScreenTraceParameters.PrevSceneColorTexture->GetParent() == SceneTextures.Color.Resolve || !PassParameters->SceneTextures.GBufferVelocityTexture) { PassParameters->SceneTextures.GBufferVelocityTexture = GSystemTextures.GetBlackDummy(GraphBuilder); } PassParameters->Substrate = Substrate::BindSubstrateGlobalUniformParameters(View); PassParameters->LightingChannelsTexture = LightingChannelsTexture; PassParameters->MaxHierarchicalScreenTraceIterations = GLumenScreenProbeGatherHierarchicalScreenTracesMaxIterations; PassParameters->RelativeDepthThickness = GLumenScreenProbeGatherRelativeDepthThickness * View.ViewMatrices.GetPerProjectionDepthThicknessScale(); PassParameters->HistoryDepthTestRelativeThickness = GLumenScreenProbeGatherHistoryDepthTestRelativeThickness * View.ViewMatrices.GetPerProjectionDepthThicknessScale(); PassParameters->NumThicknessStepsToDetermineCertainty = GLumenScreenProbeGatherHierarchicalScreenTracesSkipFoliageHits ? 0 : GLumenScreenProbeGatherNumThicknessStepsToDetermineCertainty; PassParameters->MinimumTracingThreadOccupancy = GLumenScreenProbeGatherScreenTracesMinimumOccupancy; PassParameters->SkipFoliageHits = GLumenScreenProbeGatherHierarchicalScreenTracesSkipFoliageHits; PassParameters->SkipHairHits = !SupportsHairScreenTraces(); PassParameters->BiasForTracesFromHairPixels = CVarLumenScreenProbeGatherScreenTracesHairBias.GetValueOnRenderThread(); PassParameters->ScreenProbeGatherStateFrameIndex = LumenScreenProbeGather::GetStateFrameIndex(View.ViewState); PassParameters->ScreenProbeParameters = ScreenProbeParameters; PassParameters->IndirectTracingParameters = IndirectTracingParameters; PassParameters->RadianceCacheParameters = RadianceCacheParameters; const bool bHasHairStrands = HairStrands::HasViewHairStrandsData(View) && GLumenScreenProbeGatherHairStrands_ScreenTrace > 0; if (bHasHairStrands) { PassParameters->HairStrands = HairStrands::BindHairStrandsViewUniformParameters(View); } const bool bTerminateOnLowOccupancy = GLumenScreenProbeGatherScreenTracesMinimumOccupancy > 0 && GRHISupportsWaveOperations && GRHIMinimumWaveSize <= 32 && GRHIMaximumWaveSize >= 32 && RHISupportsWaveOperations(View.GetShaderPlatform()); const bool bHZBTraversal = GLumenScreenProbeGatherHierarchicalScreenTraces != 0; FScreenProbeTraceScreenTexturesCS::FPermutationDomain PermutationVector; PermutationVector.Set< FScreenProbeTraceScreenTexturesCS::FRadianceCache >(LumenScreenProbeGather::UseRadianceCache()); PermutationVector.Set< FScreenProbeTraceScreenTexturesCS::FHierarchicalScreenTracing >(bHZBTraversal); PermutationVector.Set< FScreenProbeTraceScreenTexturesCS::FTraceFullResDepth >(bHZBTraversal && GLumenScreenProbeGatherHierarchicalScreenTracesFullResDepth != 0); PermutationVector.Set< FScreenProbeTraceScreenTexturesCS::FStructuredImportanceSampling >(LumenScreenProbeGather::UseImportanceSampling(View)); PermutationVector.Set(bHasHairStrands); PermutationVector.Set(bTerminateOnLowOccupancy); PermutationVector.Set(Lumen::IsUsingDistanceFieldRepresentationBit(View)); auto ComputeShader = View.ShaderMap->GetShader(PermutationVector); FComputeShaderUtils::AddPass( GraphBuilder, RDG_EVENT_NAME("TraceScreen(%s)", bHasHairStrands ? TEXT("Scene, HairStrands") : TEXT("Scene")), ComputePassFlags, ComputeShader, PassParameters, ScreenProbeParameters.ProbeIndirectArgs, (uint32)(EScreenProbeIndirectArgs::ThreadPerTrace) * sizeof(FRHIDispatchIndirectParameters)); }; TraceScreen(); } bool bNeedTraceHairVoxel = HairStrands::HasViewHairStrandsVoxelData(View) && GLumenScreenProbeGatherHairStrands_VoxelTrace > 0; const bool bUseHardwareRayTracing = Lumen::UseHardwareRayTracedScreenProbeGather(*View.Family); if (bUseHardwareRayTracing) { RenderHardwareRayTracingScreenProbe( GraphBuilder, Scene, SceneTextureParameters, ScreenProbeParameters, View, TracingParameters, IndirectTracingParameters, RadianceCacheParameters, ComputePassFlags); } else if (bTraceMeshObjects) { CullForCardTracing( GraphBuilder, Scene, View, FrameTemporaries, IndirectTracingParameters, /* out */ MeshSDFGridParameters, ComputePassFlags); const bool bTraceMeshSDFs = MeshSDFGridParameters.TracingParameters.DistanceFieldObjectBuffers.NumSceneObjects > 0; const bool bTraceHeightfields = Lumen::UseHeightfieldTracing(*View.Family, *Scene->GetLumenSceneData(View)); if (bTraceMeshSDFs || bTraceHeightfields) { FCompactedTraceParameters CompactedTraceParameters = LumenScreenProbeGather::CompactTraces( GraphBuilder, View, ScreenProbeParameters, true, IndirectTracingParameters.CardTraceEndDistanceFromCamera, IndirectTracingParameters.MaxMeshSDFTraceDistance, /*bCompactForSkyApply*/ false, ComputePassFlags); auto TraceMeshSDFs = [&]() { FScreenProbeTraceMeshSDFsCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); PassParameters->TracingParameters = TracingParameters; PassParameters->MeshSDFGridParameters = MeshSDFGridParameters; PassParameters->ScreenProbeParameters = ScreenProbeParameters; PassParameters->IndirectTracingParameters = IndirectTracingParameters; PassParameters->SceneTexturesStruct = SceneTextures.UniformBuffer; PassParameters->CompactedTraceParameters = CompactedTraceParameters; if (bNeedTraceHairVoxel) { PassParameters->HairStrandsVoxel = HairStrands::BindHairStrandsVoxelUniformParameters(View); } FScreenProbeTraceMeshSDFsCS::FPermutationDomain PermutationVector; PermutationVector.Set< FScreenProbeTraceMeshSDFsCS::FThreadGroupSize32 >(Lumen::UseThreadGroupSize32()); PermutationVector.Set< FScreenProbeTraceMeshSDFsCS::FStructuredImportanceSampling >(LumenScreenProbeGather::UseImportanceSampling(View)); PermutationVector.Set< FScreenProbeTraceMeshSDFsCS::FHairStrands >(bNeedTraceHairVoxel); PermutationVector.Set< FScreenProbeTraceMeshSDFsCS::FTraceMeshSDFs >(bTraceMeshSDFs); PermutationVector.Set< FScreenProbeTraceMeshSDFsCS::FTraceHeightfields >(bTraceHeightfields); extern int32 GDistanceFieldOffsetDataStructure; PermutationVector.Set< FScreenProbeTraceMeshSDFsCS::FOffsetDataStructure >(GDistanceFieldOffsetDataStructure); PermutationVector = FScreenProbeTraceMeshSDFsCS::RemapPermutation(PermutationVector); auto ComputeShader = View.ShaderMap->GetShader(PermutationVector); ECompactedTracingIndirectArgs IndirectArgsOffset = Lumen::UseThreadGroupSize32() ? ECompactedTracingIndirectArgs::NumTracesDiv32 : ECompactedTracingIndirectArgs::NumTracesDiv64; FComputeShaderUtils::AddPass( GraphBuilder, RDG_EVENT_NAME("TraceMeshSDFs(%s)", bNeedTraceHairVoxel ? TEXT("Scene, HairStrands") : TEXT("Scene")), ComputePassFlags, ComputeShader, PassParameters, CompactedTraceParameters.IndirectArgs, (int32)IndirectArgsOffset); }; TraceMeshSDFs(); bNeedTraceHairVoxel = false; } } FCompactedTraceParameters CompactedTraceParameters = LumenScreenProbeGather::CompactTraces( GraphBuilder, View, ScreenProbeParameters, false, 0.0f, FLT_MAX, // Make sure the shader runs on all misses to apply radiance cache + skylight /*bCompactForSkyApply*/ true, ComputePassFlags); auto TraceVoxels = [&]() { const bool bRadianceCache = LumenScreenProbeGather::UseRadianceCache(); FScreenProbeTraceVoxelsCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); PassParameters->RadianceCacheParameters = RadianceCacheParameters; PassParameters->TracingParameters = TracingParameters; PassParameters->ScreenProbeParameters = ScreenProbeParameters; PassParameters->IndirectTracingParameters = IndirectTracingParameters; PassParameters->SceneTexturesStruct = SceneTextures.UniformBuffer; PassParameters->CompactedTraceParameters = CompactedTraceParameters; if (bNeedTraceHairVoxel) { PassParameters->HairStrandsVoxel = HairStrands::BindHairStrandsVoxelUniformParameters(View); } FScreenProbeTraceVoxelsCS::FPermutationDomain PermutationVector; PermutationVector.Set< FScreenProbeTraceVoxelsCS::FThreadGroupSize32 >(Lumen::UseThreadGroupSize32()); PermutationVector.Set< FScreenProbeTraceVoxelsCS::FRadianceCache >(bRadianceCache); PermutationVector.Set< FScreenProbeTraceVoxelsCS::FScreenProbeExtraAO >(LumenScreenProbeGather::UseScreenProbeExtraAO()); PermutationVector.Set< FScreenProbeTraceVoxelsCS::FStructuredImportanceSampling >(LumenScreenProbeGather::UseImportanceSampling(View)); PermutationVector.Set< FScreenProbeTraceVoxelsCS::FHairStrands>(bNeedTraceHairVoxel); PermutationVector.Set< FScreenProbeTraceVoxelsCS::FTraceVoxels>(!bUseHardwareRayTracing && Lumen::UseGlobalSDFTracing(View.Family->EngineShowFlags)); PermutationVector.Set< FScreenProbeTraceVoxelsCS::FSimpleCoverageBasedExpand>(PermutationVector.Get() && Lumen::UseGlobalSDFSimpleCoverageBasedExpand()); PermutationVector = FScreenProbeTraceVoxelsCS::RemapPermutation(PermutationVector); auto ComputeShader = View.ShaderMap->GetShader(PermutationVector); ECompactedTracingIndirectArgs IndirectArgsOffset = Lumen::UseThreadGroupSize32() ? ECompactedTracingIndirectArgs::NumTracesDiv32 : ECompactedTracingIndirectArgs::NumTracesDiv64; FComputeShaderUtils::AddPass( GraphBuilder, RDG_EVENT_NAME("%s%s", bUseHardwareRayTracing ? TEXT("RadianceCacheInterpolate") : TEXT("TraceVoxels"), bNeedTraceHairVoxel ? TEXT(" and HairStrands") : TEXT("")), ComputePassFlags, ComputeShader, PassParameters, CompactedTraceParameters.IndirectArgs, (int32)IndirectArgsOffset); bNeedTraceHairVoxel = false; }; TraceVoxels(); if (GLumenScreenProbeGatherVisualizeTraces) { SetupVisualizeTraces(GraphBuilder, SceneTextures, Scene, View, ScreenProbeParameters, ComputePassFlags); } }