Files
UnrealEngine/Engine/Source/Runtime/Renderer/Private/Lumen/LumenTranslucencyRadianceCache.cpp
2025-05-18 13:04:45 +08:00

482 lines
21 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "RendererPrivate.h"
#include "ScenePrivate.h"
#include "SceneUtils.h"
#include "PipelineStateCache.h"
#include "ShaderParameterStruct.h"
#include "VolumeLighting.h"
#include "MeshPassProcessor.inl"
#include "LumenTranslucencyVolumeLighting.h"
#include "LumenRadianceCache.h"
#include "TranslucentLighting.h"
int32 GLumenTranslucencyRadianceCacheReflections = 1;
FAutoConsoleVariableRef CVarLumenTranslucencyRadianceCache(
TEXT("r.Lumen.TranslucencyReflections.RadianceCache"),
GLumenTranslucencyRadianceCacheReflections,
TEXT("Whether to use the Radiance Cache to provide Lumen Reflections on Translucent Surfaces."),
ECVF_Scalability | ECVF_RenderThreadSafe
);
int32 GLumenTranslucencyReflectionsMarkDownsampleFactor = 4;
FAutoConsoleVariableRef CVarLumenTranslucencyRadianceCacheDownsampleFactor(
TEXT("r.Lumen.TranslucencyReflections.MarkDownsampleFactor"),
GLumenTranslucencyReflectionsMarkDownsampleFactor,
TEXT("Downsample factor for marking translucent surfaces in the Lumen Radiance Cache. Too low of factors will cause incorrect Radiance Cache coverage. Should be a power of 2."),
ECVF_Scalability | ECVF_RenderThreadSafe
);
bool GLumenTranslucencyRadianceCacheHZBOcclusionTest = true;
FAutoConsoleVariableRef CVarLumenTranslucencyRadianceCacheHZBOcclusionTest(
TEXT("r.Lumen.TranslucencyReflections.HZBOcclusionTest"),
GLumenTranslucencyRadianceCacheHZBOcclusionTest,
TEXT("Whether to use HZB occlusion test when marking translucent surfaces in the Lumen Radiance Cache."),
ECVF_Scalability | ECVF_RenderThreadSafe
);
float GLumenTranslucencyReflectionsRadianceCacheReprojectionRadiusScale = 10;
FAutoConsoleVariableRef CVarLumenTranslucencyRadianceCacheReprojectionRadiusScale(
TEXT("r.Lumen.TranslucencyReflections.ReprojectionRadiusScale"),
GLumenTranslucencyReflectionsRadianceCacheReprojectionRadiusScale,
TEXT("Larger values treat the Radiance Cache lighting as more distant."),
ECVF_Scalability | ECVF_RenderThreadSafe
);
float GLumenTranslucencyVolumeRadianceCacheClipmapFadeSize = 4.0f;
FAutoConsoleVariableRef CVarLumenTranslucencyVolumeRadianceCacheClipmapFadeSize(
TEXT("r.Lumen.TranslucencyReflections.ClipmapFadeSize"),
GLumenTranslucencyVolumeRadianceCacheClipmapFadeSize,
TEXT("Size in Radiance Cache probes of the dithered transition region between clipmaps"),
ECVF_RenderThreadSafe
);
namespace Lumen
{
bool UseLumenTranslucencyRadianceCacheReflections(const FSceneViewFamily& ViewFamily)
{
return GLumenTranslucencyRadianceCacheReflections != 0 && ViewFamily.EngineShowFlags.LumenReflections;
}
bool ShouldRenderInTranslucencyRadianceCacheMarkPass(bool bShouldRenderInMainPass, const FMaterial& Material)
{
const bool bIsTranslucent = IsTranslucentBlendMode(Material);
const ETranslucencyLightingMode TranslucencyLightingMode = Material.GetTranslucencyLightingMode();
return bIsTranslucent
&& (TranslucencyLightingMode == TLM_Surface || TranslucencyLightingMode == TLM_SurfacePerPixelLighting || IsTranslucencyLightingVolumeUsingVoxelMarking())
&& bShouldRenderInMainPass
&& ShouldIncludeDomainInMeshPass(Material.GetMaterialDomain());
}
}
BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FLumenTranslucencyRadianceCacheMarkPassUniformParameters, )
SHADER_PARAMETER_STRUCT(FSceneTextureUniformParameters, SceneTextures)
SHADER_PARAMETER_STRUCT_INCLUDE(FHZBParameters, HZBParameters)
SHADER_PARAMETER(float, HZBMipLevel)
SHADER_PARAMETER(uint32, UseHZBTest)
SHADER_PARAMETER_STRUCT_INCLUDE(LumenRadianceCache::FRadianceCacheMarkParameters, RadianceCacheMarkParameters)
SHADER_PARAMETER(uint32, MarkRadianceCache)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture3D<uint>, InnerVolumeMarkTexture)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture3D<uint>, OuterVolumeMarkTexture)
SHADER_PARAMETER(FIntVector, TranslucencyLightingVolumeSize)
SHADER_PARAMETER(uint32, MarkTranslucencyLightingVolume)
END_GLOBAL_SHADER_PARAMETER_STRUCT()
IMPLEMENT_STATIC_UNIFORM_BUFFER_STRUCT(FLumenTranslucencyRadianceCacheMarkPassUniformParameters, "LumenTranslucencyRadianceCacheMarkPass", SceneTextures);
class FLumenTranslucencyRadianceCacheMarkVS : public FMeshMaterialShader
{
DECLARE_SHADER_TYPE(FLumenTranslucencyRadianceCacheMarkVS, MeshMaterial);
protected:
static bool ShouldCompilePermutation(const FMeshMaterialShaderPermutationParameters& Parameters)
{
return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5)
&& IsTranslucentBlendMode(Parameters.MaterialParameters)
&& ((DoesPlatformSupportLumenGI(Parameters.Platform) && Parameters.MaterialParameters.bIsTranslucencySurface)
|| IsTranslucencyLightingVolumeUsingVoxelMarkingSupported());
}
FLumenTranslucencyRadianceCacheMarkVS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
: FMeshMaterialShader(Initializer)
{}
FLumenTranslucencyRadianceCacheMarkVS() = default;
};
IMPLEMENT_MATERIAL_SHADER_TYPE(, FLumenTranslucencyRadianceCacheMarkVS, TEXT("/Engine/Private/Lumen/LumenTranslucencyRadianceCacheMarkShaders.usf"), TEXT("MainVS"), SF_Vertex);
class FLumenTranslucencyRadianceCacheMarkPS : public FMeshMaterialShader
{
DECLARE_SHADER_TYPE(FLumenTranslucencyRadianceCacheMarkPS, MeshMaterial);
public:
static bool ShouldCompilePermutation(const FMeshMaterialShaderPermutationParameters& Parameters)
{
return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5)
&& IsTranslucentBlendMode(Parameters.MaterialParameters)
&& ((DoesPlatformSupportLumenGI(Parameters.Platform) && Parameters.MaterialParameters.bIsTranslucencySurface)
|| IsTranslucencyLightingVolumeUsingVoxelMarkingSupported());
}
FLumenTranslucencyRadianceCacheMarkPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
: FMeshMaterialShader(Initializer)
{}
FLumenTranslucencyRadianceCacheMarkPS() = default;
};
IMPLEMENT_MATERIAL_SHADER_TYPE(, FLumenTranslucencyRadianceCacheMarkPS, TEXT("/Engine/Private/Lumen/LumenTranslucencyRadianceCacheMarkShaders.usf"), TEXT("MainPS"), SF_Pixel);
class FLumenTranslucencyRadianceCacheMarkMeshProcessor : public FSceneRenderingAllocatorObject<FLumenTranslucencyRadianceCacheMarkMeshProcessor>, public FMeshPassProcessor
{
public:
FLumenTranslucencyRadianceCacheMarkMeshProcessor(const FScene* Scene, ERHIFeatureLevel::Type FeatureLevel, const FSceneView* InViewIfDynamicMeshCommand, const FMeshPassProcessorRenderState& InPassDrawRenderState, FMeshPassDrawListContext* InDrawListContext);
virtual void AddMeshBatch(const FMeshBatch& RESTRICT MeshBatch, uint64 BatchElementMask, const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy, int32 StaticMeshId = -1) override final;
virtual void CollectPSOInitializers(const FSceneTexturesConfig& SceneTexturesConfig, const FMaterial& Material, const FPSOPrecacheVertexFactoryData& VertexFactoryData, const FPSOPrecacheParams& PreCacheParams, TArray<FPSOPrecacheData>& PSOInitializers) override final;
FMeshPassProcessorRenderState PassDrawRenderState;
};
bool GetLumenTranslucencyRadianceCacheMarkShaders(
const FMaterial& Material,
const FVertexFactoryType* VertexFactoryType,
TShaderRef<FLumenTranslucencyRadianceCacheMarkVS>& VertexShader,
TShaderRef<FLumenTranslucencyRadianceCacheMarkPS>& PixelShader)
{
FMaterialShaderTypes ShaderTypes;
ShaderTypes.AddShaderType<FLumenTranslucencyRadianceCacheMarkVS>();
ShaderTypes.AddShaderType<FLumenTranslucencyRadianceCacheMarkPS>();
FMaterialShaders Shaders;
if (!Material.TryGetShaders(ShaderTypes, VertexFactoryType, Shaders))
{
return false;
}
Shaders.TryGetVertexShader(VertexShader);
Shaders.TryGetPixelShader(PixelShader);
return true;
}
bool CanMaterialRenderInLumenTranslucencyRadianceCacheMarkPass(
const FScene& Scene,
const FSceneViewFamily& ViewFamily,
const FPrimitiveSceneProxy& PrimitiveSceneProxy,
const FMaterial& Material)
{
const FSceneView* View = ViewFamily.Views[0];
check(View);
const bool bIsTranslucencyMarkPassNeeded = ShouldRenderLumenDiffuseGI(&Scene, *View) || IsTranslucencyLightingVolumeUsingVoxelMarking();
return bIsTranslucencyMarkPassNeeded && Lumen::ShouldRenderInTranslucencyRadianceCacheMarkPass(PrimitiveSceneProxy.ShouldRenderInMainPass(), Material);
}
void FLumenTranslucencyRadianceCacheMarkMeshProcessor::AddMeshBatch(const FMeshBatch& RESTRICT MeshBatch, uint64 BatchElementMask, const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy, int32 StaticMeshId)
{
LLM_SCOPE_BYTAG(Lumen);
if (!ViewIfDynamicMeshCommand)
{
return;
}
const bool bIsTranslucencyMarkPassNeeded = ShouldRenderLumenDiffuseGI(Scene, *ViewIfDynamicMeshCommand) || IsTranslucencyLightingVolumeUsingVoxelMarking();
if (MeshBatch.bUseForMaterial
&& PrimitiveSceneProxy
//@todo - this filter should be done at a higher level
&& bIsTranslucencyMarkPassNeeded)
{
const FMaterialRenderProxy* MaterialRenderProxy = MeshBatch.MaterialRenderProxy;
while (MaterialRenderProxy)
{
const FMaterial* Material = MaterialRenderProxy->GetMaterialNoFallback(FeatureLevel);
if (Material)
{
auto TryAddMeshBatch = [this](const FMeshBatch& RESTRICT MeshBatch, uint64 BatchElementMask, const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy, int32 StaticMeshId, const FMaterialRenderProxy& MaterialRenderProxy, const FMaterial& Material) -> bool
{
if (Lumen::ShouldRenderInTranslucencyRadianceCacheMarkPass(PrimitiveSceneProxy->ShouldRenderInMainPass(), Material))
{
const FVertexFactory* VertexFactory = MeshBatch.VertexFactory;
FVertexFactoryType* VertexFactoryType = VertexFactory->GetType();
TMeshProcessorShaders<
FLumenTranslucencyRadianceCacheMarkVS,
FLumenTranslucencyRadianceCacheMarkPS> PassShaders;
if (!GetLumenTranslucencyRadianceCacheMarkShaders(
Material,
VertexFactory->GetType(),
PassShaders.VertexShader,
PassShaders.PixelShader))
{
return false;
}
FMeshMaterialShaderElementData ShaderElementData;
ShaderElementData.InitializeMeshMaterialData(ViewIfDynamicMeshCommand, PrimitiveSceneProxy, MeshBatch, StaticMeshId, false);
const FMeshDrawingPolicyOverrideSettings OverrideSettings = ComputeMeshOverrideSettings(MeshBatch);
const ERasterizerFillMode MeshFillMode = ComputeMeshFillMode(Material, OverrideSettings);
const ERasterizerCullMode MeshCullMode = ComputeMeshCullMode(Material, OverrideSettings);
const FMeshDrawCommandSortKey SortKey = CalculateMeshStaticSortKey(PassShaders.VertexShader, PassShaders.PixelShader);
BuildMeshDrawCommands(
MeshBatch,
BatchElementMask,
PrimitiveSceneProxy,
MaterialRenderProxy,
Material,
PassDrawRenderState,
PassShaders,
MeshFillMode,
MeshCullMode,
SortKey,
EMeshPassFeatures::Default,
ShaderElementData);
}
return true;
};
if (TryAddMeshBatch(MeshBatch, BatchElementMask, PrimitiveSceneProxy, StaticMeshId, *MaterialRenderProxy, *Material))
{
break;
}
}
MaterialRenderProxy = MaterialRenderProxy->GetFallback(FeatureLevel);
}
}
}
void FLumenTranslucencyRadianceCacheMarkMeshProcessor::CollectPSOInitializers(const FSceneTexturesConfig& SceneTexturesConfig, const FMaterial& Material, const FPSOPrecacheVertexFactoryData& VertexFactoryData, const FPSOPrecacheParams& PreCacheParams, TArray<FPSOPrecacheData>& PSOInitializers)
{
LLM_SCOPE_BYTAG(Lumen);
if (PreCacheParams.bRenderInMainPass && !Lumen::ShouldRenderInTranslucencyRadianceCacheMarkPass(PreCacheParams.bRenderInMainPass, Material))
{
return;
}
const FMeshDrawingPolicyOverrideSettings OverrideSettings = ComputeMeshOverrideSettings(PreCacheParams);
const ERasterizerFillMode MeshFillMode = ComputeMeshFillMode(Material, OverrideSettings);
const ERasterizerCullMode MeshCullMode = ComputeMeshCullMode(Material, OverrideSettings);
TMeshProcessorShaders<
FLumenTranslucencyRadianceCacheMarkVS,
FLumenTranslucencyRadianceCacheMarkPS> PassShaders;
if (!GetLumenTranslucencyRadianceCacheMarkShaders(
Material,
VertexFactoryData.VertexFactoryType,
PassShaders.VertexShader,
PassShaders.PixelShader))
{
return;
}
FGraphicsPipelineRenderTargetsInfo RenderTargetsInfo;
AddGraphicsPipelineStateInitializer(
VertexFactoryData,
Material,
PassDrawRenderState,
RenderTargetsInfo,
PassShaders,
MeshFillMode,
MeshCullMode,
(EPrimitiveType)PreCacheParams.PrimitiveType,
EMeshPassFeatures::Default,
true /*bRequired*/,
PSOInitializers);
}
FLumenTranslucencyRadianceCacheMarkMeshProcessor::FLumenTranslucencyRadianceCacheMarkMeshProcessor(const FScene* Scene, ERHIFeatureLevel::Type FeatureLevel, const FSceneView* InViewIfDynamicMeshCommand, const FMeshPassProcessorRenderState& InPassDrawRenderState, FMeshPassDrawListContext* InDrawListContext)
: FMeshPassProcessor(EMeshPass::LumenTranslucencyRadianceCacheMark, Scene, FeatureLevel, InViewIfDynamicMeshCommand, InDrawListContext)
, PassDrawRenderState(InPassDrawRenderState)
{}
FMeshPassProcessor* CreateLumenTranslucencyRadianceCacheMarkPassProcessor(ERHIFeatureLevel::Type FeatureLevel, const FScene* Scene, const FSceneView* InViewIfDynamicMeshCommand, FMeshPassDrawListContext* InDrawListContext)
{
LLM_SCOPE_BYTAG(Lumen);
FMeshPassProcessorRenderState PassState;
// We use HZB tests in the shader instead of hardware depth testing
PassState.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());
PassState.SetBlendState(TStaticBlendState<>::GetRHI());
return new FLumenTranslucencyRadianceCacheMarkMeshProcessor(Scene, FeatureLevel, InViewIfDynamicMeshCommand, PassState, InDrawListContext);
}
REGISTER_MESHPASSPROCESSOR_AND_PSOCOLLECTOR(LumenTranslucencyRadianceCacheMarkPass, CreateLumenTranslucencyRadianceCacheMarkPassProcessor, EShadingPath::Deferred, EMeshPass::LumenTranslucencyRadianceCacheMark, EMeshPassFlags::MainView);
BEGIN_SHADER_PARAMETER_STRUCT(FLumenTranslucencyRadianceCacheMarkParameters, )
SHADER_PARAMETER_STRUCT_INCLUDE(FViewShaderParameters, View)
SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FLumenTranslucencyRadianceCacheMarkPassUniformParameters, MarkPass)
SHADER_PARAMETER_STRUCT_INCLUDE(FInstanceCullingDrawParams, InstanceCullingDrawParams)
RENDER_TARGET_BINDING_SLOTS()
END_SHADER_PARAMETER_STRUCT()
extern int32 GetTranslucencyLightingVolumeDim();
void LumenTranslucencyReflectionsMarkUsedProbes(
FRDGBuilder& GraphBuilder,
const FSceneRenderer& SceneRenderer,
FViewInfo& View,
const FSceneTextures& SceneTextures,
const LumenRadianceCache::FRadianceCacheMarkParameters* RadianceCacheMarkParameters)
{
check(GLumenTranslucencyRadianceCacheReflections != 0);
const EMeshPass::Type MeshPass = EMeshPass::LumenTranslucencyRadianceCacheMark;
const float ViewportScale = 1.0f / GLumenTranslucencyReflectionsMarkDownsampleFactor;
FIntRect DownsampledViewRect = GetScaledRect(View.ViewRect, ViewportScale);
auto* Pass = View.ParallelMeshDrawCommandPasses[MeshPass];
if (!Pass)
{
return;
}
View.BeginRenderView();
FLumenTranslucencyRadianceCacheMarkParameters* PassParameters = GraphBuilder.AllocParameters<FLumenTranslucencyRadianceCacheMarkParameters>();
{
FViewUniformShaderParameters DownsampledTranslucencyViewParameters = *View.CachedViewUniformShaderParameters;
FViewMatrices ViewMatrices = View.ViewMatrices;
FViewMatrices PrevViewMatrices = View.PrevViewInfo.ViewMatrices;
// Update the parts of DownsampledTranslucencyParameters which are dependent on the buffer size and view rect
View.SetupViewRectUniformBufferParameters(
DownsampledTranslucencyViewParameters,
SceneTextures.Config.Extent,
DownsampledViewRect,
ViewMatrices,
PrevViewMatrices);
PassParameters->View.View = TUniformBufferRef<FViewUniformShaderParameters>::CreateUniformBufferImmediate(DownsampledTranslucencyViewParameters, UniformBuffer_SingleFrame);
if (View.bShouldBindInstancedViewUB)
{
FInstancedViewUniformShaderParameters LocalInstancedViewUniformShaderParameters;
InstancedViewParametersUtils::CopyIntoInstancedViewParameters(LocalInstancedViewUniformShaderParameters, DownsampledTranslucencyViewParameters, 0);
if (const FViewInfo* InstancedView = View.GetInstancedView())
{
InstancedView->SetupViewRectUniformBufferParameters(
DownsampledTranslucencyViewParameters,
SceneTextures.Config.Extent,
GetScaledRect(InstancedView->ViewRect, ViewportScale),
ViewMatrices,
PrevViewMatrices);
InstancedViewParametersUtils::CopyIntoInstancedViewParameters(LocalInstancedViewUniformShaderParameters, DownsampledTranslucencyViewParameters, 1);
}
PassParameters->View.InstancedView = TUniformBufferRef<FInstancedViewUniformShaderParameters>::CreateUniformBufferImmediate(
reinterpret_cast<const FInstancedViewUniformShaderParameters&>(LocalInstancedViewUniformShaderParameters),
UniformBuffer_SingleFrame);
}
}
const bool bMarkRadianceCache = (RadianceCacheMarkParameters != nullptr);
LumenRadianceCache::FRadianceCacheMarkParameters NullPlaceholder;
if (RadianceCacheMarkParameters == nullptr)
{
FRDGTextureRef PlaceholderTexture = GraphBuilder.CreateTexture(
FRDGTextureDesc::Create3D(FIntVector(4,4,4), PF_R8_UINT, FClearValueBinding::Black, TexCreate_ShaderResource | TexCreate_UAV),
TEXT("LumenRadianceCacheMarkPlaceholder"));
NullPlaceholder.RWRadianceProbeIndirectionTexture = GraphBuilder.CreateUAV(PlaceholderTexture);
RadianceCacheMarkParameters = &NullPlaceholder;
}
const FIntVector TranslucencyLightingVolumeDim(GetTranslucencyLightingVolumeDim());
FRDGTextureUAVRef InnerVolumeMarkTextureUAV = nullptr;
FRDGTextureUAVRef OuterVolumeMarkTextureUAV = nullptr;
const bool bMarkTranslucencyLightingVolume = IsTranslucencyLightingVolumeUsingVoxelMarking();
if (bMarkTranslucencyLightingVolume)
{
View.TranslucencyVolumeMarkData[0].MarkTexture = GraphBuilder.CreateTexture(
FRDGTextureDesc::Create3D(TranslucencyLightingVolumeDim, PF_R8_UINT, FClearValueBinding::Black, TexCreate_ShaderResource | TexCreate_UAV),
TEXT("TranslucencyLightVolume.InnerMarkTexture"));
View.TranslucencyVolumeMarkData[1].MarkTexture = GraphBuilder.CreateTexture(
FRDGTextureDesc::Create3D(TranslucencyLightingVolumeDim, PF_R8_UINT, FClearValueBinding::Black, TexCreate_ShaderResource | TexCreate_UAV),
TEXT("TranslucencyLightVolume.OuterMarkTexture"));
InnerVolumeMarkTextureUAV = GraphBuilder.CreateUAV(View.TranslucencyVolumeMarkData[0].MarkTexture);
OuterVolumeMarkTextureUAV = GraphBuilder.CreateUAV(View.TranslucencyVolumeMarkData[1].MarkTexture);
AddClearUAVPass(GraphBuilder, InnerVolumeMarkTextureUAV, 0u);
AddClearUAVPass(GraphBuilder, OuterVolumeMarkTextureUAV, 0u);
}
else
{
FRDGTextureRef PlaceholderTexture0 = GraphBuilder.CreateTexture(
FRDGTextureDesc::Create3D(FIntVector(4, 4, 4), PF_R8_UINT, FClearValueBinding::Black, TexCreate_ShaderResource | TexCreate_UAV),
TEXT("TranslucencyLightVolume.InnerMarkTexture.Placeholder"));
FRDGTextureRef PlaceholderTexture1 = GraphBuilder.CreateTexture(
FRDGTextureDesc::Create3D(FIntVector(4, 4, 4), PF_R8_UINT, FClearValueBinding::Black, TexCreate_ShaderResource | TexCreate_UAV),
TEXT("TranslucencyLightVolume.OuterMarkTexture.Placeholder"));
InnerVolumeMarkTextureUAV = GraphBuilder.CreateUAV(PlaceholderTexture0);
OuterVolumeMarkTextureUAV = GraphBuilder.CreateUAV(PlaceholderTexture1);
}
{
FLumenTranslucencyRadianceCacheMarkPassUniformParameters& MarkPassParameters = *GraphBuilder.AllocParameters<FLumenTranslucencyRadianceCacheMarkPassUniformParameters>();
SetupSceneTextureUniformParameters(GraphBuilder, &SceneTextures, View.FeatureLevel, ESceneTextureSetupMode::All, MarkPassParameters.SceneTextures);
MarkPassParameters.RadianceCacheMarkParameters = *RadianceCacheMarkParameters;
MarkPassParameters.RadianceCacheMarkParameters.InvClipmapFadeSizeForMark = 1.0f / FMath::Clamp(GLumenTranslucencyVolumeRadianceCacheClipmapFadeSize, .001f, 16.0f);
MarkPassParameters.MarkRadianceCache = bMarkRadianceCache ? 1 : 0;
MarkPassParameters.HZBParameters = GetHZBParameters(GraphBuilder, View, EHZBType::FurthestHZB);
MarkPassParameters.HZBMipLevel = FMath::Max<float>((int32)FMath::FloorLog2((float)GLumenTranslucencyReflectionsMarkDownsampleFactor) - 1, 0.0f);
MarkPassParameters.UseHZBTest = GLumenTranslucencyRadianceCacheHZBOcclusionTest ? 1 : 0;
MarkPassParameters.InnerVolumeMarkTexture = InnerVolumeMarkTextureUAV;
MarkPassParameters.OuterVolumeMarkTexture = OuterVolumeMarkTextureUAV;
MarkPassParameters.TranslucencyLightingVolumeSize = TranslucencyLightingVolumeDim;
MarkPassParameters.MarkTranslucencyLightingVolume = bMarkTranslucencyLightingVolume ? 1 : 0;
PassParameters->MarkPass = GraphBuilder.CreateUniformBuffer(&MarkPassParameters);
}
Pass->BuildRenderingCommands(GraphBuilder, SceneRenderer.Scene->GPUScene, PassParameters->InstanceCullingDrawParams);
GraphBuilder.AddPass(
RDG_EVENT_NAME("TranslucentSurfacesMarkPass"),
PassParameters,
ERDGPassFlags::Raster | ERDGPassFlags::SkipRenderPass,
[&View, Pass, &SceneRenderer, MeshPass, PassParameters, ViewportScale, DownsampledViewRect](FRDGAsyncTask, FRHICommandList& RHICmdList)
{
FRHIRenderPassInfo RPInfo;
RPInfo.ResolveRect = FResolveRect(DownsampledViewRect);
RHICmdList.BeginRenderPass(RPInfo, TEXT("LumenTranslucencyRadianceCacheMark"));
FSceneRenderer::SetStereoViewport(RHICmdList, View, ViewportScale);
Pass->Draw(RHICmdList, &PassParameters->InstanceCullingDrawParams);
RHICmdList.EndRenderPass();
});
}