共5个Pass
第一个Pass:
// Batch clear all resources required for the subsequent card context update pass
{
FClearCardUpdateContextCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FClearCardUpdateContextCS::FParameters>();
PassParameters->RWDirectLightingCardPageIndexAllocator = DirectCardPageIndexAllocatorUAV;
PassParameters->RWIndirectLightingCardPageIndexAllocator = IndirectCardPageIndexAllocatorUAV;
PassParameters->RWMaxUpdateBucket = MaxUpdateBucketUAV;
PassParameters->RWCardPageTileAllocator = CardPageTileAllocatorUAV;
PassParameters->RWPriorityHistogram = PriorityHistogramUAV;
auto ComputeShader = Views[0].ShaderMap->GetShader<FClearCardUpdateContextCS>();
const FIntVector GroupSize(FMath::DivideAndRoundUp<int32>(LumenCardUpdateContext::CARD_UPDATE_CONTEXT_MAX * LumenCardUpdateContext::PRIORITY_HISTOGRAM_SIZE, FClearCardUpdateContextCS::GetGroupSize()), 1, 1);
FComputeShaderUtils::AddPass(
GraphBuilder,
RDG_EVENT_NAME("ClearCardUpdateContext"),
ComputePassFlags,
ComputeShader,
PassParameters,
GroupSize);
}
class FClearCardUpdateContextCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FClearCardUpdateContextCS);
SHADER_USE_PARAMETER_STRUCT(FClearCardUpdateContextCS, FGlobalShader);
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<uint>, RWDirectLightingCardPageIndexAllocator)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<uint>, RWIndirectLightingCardPageIndexAllocator)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<uint>, RWMaxUpdateBucket)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<uint>, RWCardPageTileAllocator)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<uint>, RWPriorityHistogram)
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);
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE"), GetGroupSize());
}
static int32 GetGroupSize()
{
return 64;
}
};
IMPLEMENT_GLOBAL_SHADER(FClearCardUpdateContextCS, "/Engine/Private/Lumen/LumenSceneLighting.usf", "ClearCardUpdateContextCS", SF_Compute);
#define CARD_UPDATE_CONTEXT_DIRECT_LIGHTING 0
#define CARD_UPDATE_CONTEXT_INDIRECT_LIGHTING 1
#define CARD_UPDATE_CONTEXT_MAX 2
#define PRIORITY_HISTOGRAM_SIZE 128
#define MAX_UPDATE_FREQUENCY 7.0f
// [BucketIndex; NumBucketTiles]
#define MAX_UPDATE_BUCKET_STRIDE 2
// [NumAllocatedTiles; NumAllocatedTilesInLastBucket]
#define CARD_PAGE_TILE_ALLOCATOR_STRIDE 2
RWStructuredBuffer<float4> RWCardPageBuffer;
StructuredBuffer<uint> CardPageLastUsedBuffer;
StructuredBuffer<uint> CardPageHighResLastUsedBuffer;
RWStructuredBuffer<uint> RWDirectLightingCardPageIndexAllocator;
RWStructuredBuffer<uint> RWDirectLightingCardPageIndexData;
RWStructuredBuffer<uint> RWIndirectLightingCardPageIndexAllocator;
RWStructuredBuffer<uint> RWIndirectLightingCardPageIndexData;
RWStructuredBuffer<uint> RWPriorityHistogram;
StructuredBuffer<uint> PriorityHistogram;
RWStructuredBuffer<uint> RWMaxUpdateBucket;
StructuredBuffer<uint> MaxUpdateBucket;
RWStructuredBuffer<uint> RWCardPageTileAllocator;
StructuredBuffer<uint> CardPageTileAllocator;
[numthreads(THREADGROUP_SIZE, 1, 1)]
void ClearCardUpdateContextCS(
uint3 DispatchThreadId : SV_DispatchThreadID)
{
uint ElementIndex = DispatchThreadId.x;
if (ElementIndex < 1)
{
RWDirectLightingCardPageIndexAllocator[ElementIndex] = 0;
RWIndirectLightingCardPageIndexAllocator[ElementIndex] = 0;
}
if (ElementIndex < CARD_UPDATE_CONTEXT_MAX * MAX_UPDATE_BUCKET_STRIDE)
{
RWMaxUpdateBucket[ElementIndex] = 0;
}
if (ElementIndex < CARD_UPDATE_CONTEXT_MAX * CARD_PAGE_TILE_ALLOCATOR_STRIDE)
{
RWCardPageTileAllocator[ElementIndex] = 0;
}
if (ElementIndex < CARD_UPDATE_CONTEXT_MAX * PRIORITY_HISTOGRAM_SIZE)
{
RWPriorityHistogram[ElementIndex] = 0;
}
}
第五个pass,SetCardPageIndexIndirectArgs
LumenSceneLighting.usf
RWBuffer<uint> RWDirectLightingDrawCardPageIndicesIndirectArgs;
RWBuffer<uint> RWDirectLightingDispatchCardPageIndicesIndirectArgs;
RWBuffer<uint> RWIndirectLightingDrawCardPageIndicesIndirectArgs;
RWBuffer<uint> RWIndirectLightingDispatchCardPageIndicesIndirectArgs;
StructuredBuffer<uint> DirectLightingCardPageIndexAllocator;
StructuredBuffer<uint> IndirectLightingCardPageIndexAllocator;
[numthreads( 64 , 1, 1)]
void SetCardPageIndexIndirectArgsCS(uint3 DispatchThreadId : SV_DispatchThreadID)
{
if (DispatchThreadId.x == 0)
{
{
uint NumPageIndices = DirectLightingCardPageIndexAllocator[0];
RWDirectLightingDrawCardPageIndicesIndirectArgs[0] = VertexCountPerInstanceIndirect;
RWDirectLightingDrawCardPageIndicesIndirectArgs[1] = NumPageIndices;
RWDirectLightingDrawCardPageIndicesIndirectArgs[2] = 0;
RWDirectLightingDrawCardPageIndicesIndirectArgs[3] = 0;
RWDirectLightingDispatchCardPageIndicesIndirectArgs[0] = (NumPageIndices + 63) / 64;
RWDirectLightingDispatchCardPageIndicesIndirectArgs[1] = 1;
RWDirectLightingDispatchCardPageIndicesIndirectArgs[2] = 1;
RWDirectLightingDispatchCardPageIndicesIndirectArgs[3 + 0] = 4 * NumPageIndices;
RWDirectLightingDispatchCardPageIndicesIndirectArgs[3 + 1] = 1;
RWDirectLightingDispatchCardPageIndicesIndirectArgs[3 + 2] = 1;
}
{
uint NumPageIndices = IndirectLightingCardPageIndexAllocator[0];
RWIndirectLightingDrawCardPageIndicesIndirectArgs[0] = VertexCountPerInstanceIndirect;
RWIndirectLightingDrawCardPageIndicesIndirectArgs[1] = NumPageIndices;
RWIndirectLightingDrawCardPageIndicesIndirectArgs[2] = 0;
RWIndirectLightingDrawCardPageIndicesIndirectArgs[3] = 0;
RWIndirectLightingDispatchCardPageIndicesIndirectArgs[0] = (NumPageIndices + 63) / 64;
RWIndirectLightingDispatchCardPageIndicesIndirectArgs[1] = 1;
RWIndirectLightingDispatchCardPageIndicesIndirectArgs[2] = 1;
RWIndirectLightingDispatchCardPageIndicesIndirectArgs[3 + 0] = 4 * NumPageIndices;
RWIndirectLightingDispatchCardPageIndicesIndirectArgs[3 + 1] = 1;
RWIndirectLightingDispatchCardPageIndicesIndirectArgs[3 + 2] = 1;
}
}
}
LumenSceneLighting.cpp
// Setup indirect args
{
FSetCardPageIndexIndirectArgsCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FSetCardPageIndexIndirectArgsCS::FParameters>();
PassParameters->RWDirectLightingDrawCardPageIndicesIndirectArgs = GraphBuilder.CreateUAV(DirectLightingCardUpdateContext.DrawCardPageIndicesIndirectArgs);
PassParameters->RWDirectLightingDispatchCardPageIndicesIndirectArgs = GraphBuilder.CreateUAV(DirectLightingCardUpdateContext.DispatchCardPageIndicesIndirectArgs);
PassParameters->RWIndirectLightingDrawCardPageIndicesIndirectArgs = GraphBuilder.CreateUAV(IndirectLightingCardUpdateContext.DrawCardPageIndicesIndirectArgs);
PassParameters->RWIndirectLightingDispatchCardPageIndicesIndirectArgs = GraphBuilder.CreateUAV(IndirectLightingCardUpdateContext.DispatchCardPageIndicesIndirectArgs);
PassParameters->DirectLightingCardPageIndexAllocator = DirectCardPageIndexAllocatorSRV;
PassParameters->IndirectLightingCardPageIndexAllocator = IndirectCardPageIndexAllocatorSRV;
PassParameters->VertexCountPerInstanceIndirect = GRHISupportsRectTopology ? 3 : 6;
auto ComputeShader = Views[0].ShaderMap->GetShader<FSetCardPageIndexIndirectArgsCS>();
FComputeShaderUtils::AddPass(
GraphBuilder,
RDG_EVENT_NAME("SetCardPageIndexIndirectArgs"),
ComputePassFlags,
ComputeShader,
PassParameters,
FIntVector(1, 1, 1));
}