771 lines
40 KiB
C++
771 lines
40 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 "PixelShaderUtils.h"
|
|
#include "ReflectionEnvironment.h"
|
|
#include "DistanceFieldAmbientOcclusion.h"
|
|
#include "SceneTextureParameters.h"
|
|
#include "IndirectLightRendering.h"
|
|
#include "LumenRadianceCache.h"
|
|
#include "LumenRadianceCacheInternal.h"
|
|
#include "RayTracing/RaytracingOptions.h"
|
|
#include "RayTracing/RayTracingLighting.h"
|
|
#include "LumenHardwareRayTracingCommon.h"
|
|
#include "LumenScreenProbeGather.h"
|
|
|
|
static TAutoConsoleVariable<int32> CVarLumenRadianceCacheHardwareRayTracing(
|
|
TEXT("r.Lumen.RadianceCache.HardwareRayTracing"),
|
|
1,
|
|
TEXT("Enables hardware ray tracing for Lumen radiance cache (Default = 1)"),
|
|
ECVF_Scalability | ECVF_RenderThreadSafe
|
|
);
|
|
|
|
static TAutoConsoleVariable<int32> CVarLumenRadianceCacheTemporaryBufferAllocationDownsampleFactor(
|
|
TEXT("r.Lumen.RadianceCache.HardwareRayTracing.TemporaryBufferAllocationDownsampleFactor"),
|
|
32,
|
|
TEXT("Downsample factor on the temporary buffer used by Hardware Ray Tracing Radiance Cache. Higher downsample factors save more transient allocator memory, but may cause overflow and artifacts."),
|
|
ECVF_Scalability | ECVF_RenderThreadSafe
|
|
);
|
|
|
|
static TAutoConsoleVariable<int32> CVarLumenRadianceCacheHardwareRayTracingFarField(
|
|
TEXT("r.Lumen.RadianceCache.HardwareRayTracing.FarField"),
|
|
1,
|
|
TEXT("Determines whether a second trace will be fired for far-field contribution (Default = 1)"),
|
|
ECVF_Scalability | ECVF_RenderThreadSafe
|
|
);
|
|
|
|
namespace Lumen
|
|
{
|
|
bool UseHardwareRayTracedRadianceCache(const FSceneViewFamily& ViewFamily)
|
|
{
|
|
#if RHI_RAYTRACING
|
|
return IsRayTracingEnabled()
|
|
&& Lumen::UseHardwareRayTracing(ViewFamily)
|
|
&& (CVarLumenRadianceCacheHardwareRayTracing.GetValueOnRenderThread() != 0 || Lumen::UseLumenTranslucencyRadianceCacheReflections(ViewFamily) || Lumen::UseHardwareRayTracedTranslucencyVolume(ViewFamily));
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
bool LumenRadianceCache::UseHitLighting(const FViewInfo& View, EDiffuseIndirectMethod DiffuseIndirectMethod)
|
|
{
|
|
if (LumenHardwareRayTracing::IsRayGenSupported())
|
|
{
|
|
return LumenHardwareRayTracing::GetHitLightingMode(View, DiffuseIndirectMethod) == LumenHardwareRayTracing::EHitLightingMode::HitLighting;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#if RHI_RAYTRACING
|
|
|
|
namespace LumenRadianceCache
|
|
{
|
|
static constexpr int32 MaxBatchSize = 2;
|
|
|
|
enum class ERayTracingPass
|
|
{
|
|
Default,
|
|
FarField,
|
|
HitLighting,
|
|
|
|
MAX
|
|
};
|
|
|
|
BEGIN_SHADER_PARAMETER_STRUCT(FRadianceCacheTracingParameters, )
|
|
SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer<float4>, ProbeTraceData)
|
|
SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer<uint>, ProbeTraceTileAllocator)
|
|
SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer<uint2>, ProbeTraceTileData)
|
|
SHADER_PARAMETER_ARRAY(FVector4f, RadianceProbeSettings, [LumenRadianceCache::MaxClipmaps])
|
|
SHADER_PARAMETER(uint32, RadianceProbeResolution)
|
|
SHADER_PARAMETER(uint32, ProbeAtlasResolutionModuloMask)
|
|
SHADER_PARAMETER(uint32, ProbeAtlasResolutionDivideShift)
|
|
SHADER_PARAMETER(uint32, FarField)
|
|
SHADER_PARAMETER(uint32, SkyVisibility)
|
|
SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer<uint>, CompactedTraceTexelAllocator)
|
|
SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer<uint>, CompactedTraceTexelData)
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
|
|
BEGIN_SHADER_PARAMETER_STRUCT(FBatchRadianceCacheTracingParameters, )
|
|
SHADER_PARAMETER_STRUCT_INCLUDE(FLumenIndirectTracingParameters, IndirectTracingParameters)
|
|
SHADER_PARAMETER_STRUCT_ARRAY(FRadianceCacheTracingParameters, RadianceCache, [MaxBatchSize])
|
|
SHADER_PARAMETER(uint32, TempAtlasNumTraceTiles)
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
}
|
|
|
|
class FLumenRadianceCacheHardwareRayTracing : public FLumenHardwareRayTracingShaderBase
|
|
{
|
|
DECLARE_LUMEN_RAYTRACING_SHADER(FLumenRadianceCacheHardwareRayTracing)
|
|
|
|
// Parameters
|
|
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
|
RDG_BUFFER_ACCESS(HardwareRayTracingIndirectArgs, ERHIAccess::IndirectArgs | ERHIAccess::SRVCompute)
|
|
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float3>, RWTraceRadianceTexture)
|
|
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float>, RWTraceSkyVisibilityTexture)
|
|
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float>, RWTraceHitTexture)
|
|
SHADER_PARAMETER_STRUCT_INCLUDE(FLumenHardwareRayTracingShaderBase::FSharedParameters, SharedParameters)
|
|
SHADER_PARAMETER_STRUCT_INCLUDE(LumenRadianceCache::FBatchRadianceCacheTracingParameters, BatchTracingParameters)
|
|
SHADER_PARAMETER(uint32, HitLightingForceOpaque)
|
|
SHADER_PARAMETER(uint32, HitLightingShadowMode)
|
|
SHADER_PARAMETER(uint32, HitLightingShadowTranslucencyMode)
|
|
SHADER_PARAMETER(uint32, HitLightingDirectLighting)
|
|
SHADER_PARAMETER(uint32, HitLightingSkylight)
|
|
SHADER_PARAMETER(float, FarFieldBias)
|
|
SHADER_PARAMETER(float, NearFieldMaxTraceDistance)
|
|
SHADER_PARAMETER(float, NearFieldSceneRadius)
|
|
SHADER_PARAMETER(float, FarFieldMaxTraceDistance)
|
|
SHADER_PARAMETER(float, PullbackBias)
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
|
|
class FRayTracingPass : SHADER_PERMUTATION_ENUM_CLASS("RAY_TRACING_PASS", LumenRadianceCache::ERayTracingPass);
|
|
class FUseShaderExecutionReordering : SHADER_PERMUTATION_BOOL("RAY_TRACING_USE_SER");
|
|
class FSurfaceCacheAlphaMasking : SHADER_PERMUTATION_BOOL("SURFACE_CACHE_ALPHA_MASKING");
|
|
class FFarFieldOcclusionOnly : SHADER_PERMUTATION_BOOL("FAR_FIELD_OCCLUSION_ONLY");
|
|
class FRadianceCacheSkyVisibility : SHADER_PERMUTATION_BOOL("RADIANCE_CACHE_SKY_VISIBILITY");
|
|
class FRadianceCacheBatchSize : SHADER_PERMUTATION_RANGE_INT("RADIANCE_CACHE_BATCH_SIZE", 1, LumenRadianceCache::MaxBatchSize);
|
|
using FPermutationDomain = TShaderPermutationDomain<FLumenHardwareRayTracingShaderBase::FBasePermutationDomain, FRayTracingPass, FUseShaderExecutionReordering, FSurfaceCacheAlphaMasking, FFarFieldOcclusionOnly, FRadianceCacheSkyVisibility, FRadianceCacheBatchSize>;
|
|
|
|
static FPermutationDomain RemapPermutation(FPermutationDomain PermutationVector)
|
|
{
|
|
if (PermutationVector.Get<FRayTracingPass>() == LumenRadianceCache::ERayTracingPass::Default)
|
|
{
|
|
PermutationVector.Set<FFarFieldOcclusionOnly>(false);
|
|
}
|
|
else if (PermutationVector.Get<FRayTracingPass>() == LumenRadianceCache::ERayTracingPass::FarField)
|
|
{
|
|
PermutationVector.Set<FSurfaceCacheAlphaMasking>(false);
|
|
}
|
|
else
|
|
{
|
|
PermutationVector.Set<FFarFieldOcclusionOnly>(false);
|
|
PermutationVector.Set<FSurfaceCacheAlphaMasking>(false);
|
|
}
|
|
|
|
if (PermutationVector.Get<FRayTracingPass>() != LumenRadianceCache::ERayTracingPass::HitLighting)
|
|
{
|
|
PermutationVector.Set<FUseShaderExecutionReordering>(false);
|
|
}
|
|
|
|
|
|
return PermutationVector;
|
|
}
|
|
|
|
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters, Lumen::ERayTracingShaderDispatchType ShaderDispatchType)
|
|
{
|
|
FPermutationDomain PermutationVector(Parameters.PermutationId);
|
|
if (RemapPermutation(PermutationVector) != PermutationVector)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (ShaderDispatchType == Lumen::ERayTracingShaderDispatchType::Inline && PermutationVector.Get<FRayTracingPass>() == LumenRadianceCache::ERayTracingPass::HitLighting)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Does platform support SER?
|
|
if (PermutationVector.Get<FUseShaderExecutionReordering>() && !FDataDrivenShaderPlatformInfo::GetSupportsShaderExecutionReordering(Parameters.Platform))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return DoesPlatformSupportLumenGI(Parameters.Platform)
|
|
&& FLumenHardwareRayTracingShaderBase::ShouldCompilePermutation(Parameters, ShaderDispatchType);
|
|
}
|
|
|
|
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, Lumen::ERayTracingShaderDispatchType ShaderDispatchType, FShaderCompilerEnvironment& OutEnvironment)
|
|
{
|
|
FLumenHardwareRayTracingShaderBase::ModifyCompilationEnvironment(Parameters, ShaderDispatchType, Lumen::ESurfaceCacheSampling::AlwaysResidentPagesWithoutFeedback, OutEnvironment);
|
|
|
|
FPermutationDomain PermutationVector(Parameters.PermutationId);
|
|
OutEnvironment.SetDefine(TEXT("ENABLE_NEAR_FIELD_TRACING"), PermutationVector.Get<FRayTracingPass>() == LumenRadianceCache::ERayTracingPass::Default ? 1 : 0);
|
|
OutEnvironment.SetDefine(TEXT("ENABLE_FAR_FIELD_TRACING"), PermutationVector.Get<FRayTracingPass>() == LumenRadianceCache::ERayTracingPass::FarField ? 1 : 0);
|
|
}
|
|
|
|
static ERayTracingPayloadType GetRayTracingPayloadType(const int32 PermutationId)
|
|
{
|
|
FPermutationDomain PermutationVector(PermutationId);
|
|
if (PermutationVector.Get<FRayTracingPass>() == LumenRadianceCache::ERayTracingPass::HitLighting)
|
|
{
|
|
return ERayTracingPayloadType::RayTracingMaterial;
|
|
}
|
|
else
|
|
{
|
|
return ERayTracingPayloadType::LumenMinimal;
|
|
}
|
|
}
|
|
|
|
static uint32 GetGroupSize()
|
|
{
|
|
return LumenRadianceCache::TRACE_TILE_SIZE_2D;
|
|
}
|
|
};
|
|
|
|
IMPLEMENT_LUMEN_RAYGEN_AND_COMPUTE_RAYTRACING_SHADERS(FLumenRadianceCacheHardwareRayTracing)
|
|
|
|
IMPLEMENT_GLOBAL_SHADER(FLumenRadianceCacheHardwareRayTracingCS, "/Engine/Private/Lumen/LumenRadianceCacheHardwareRayTracing.usf", "LumenRadianceCacheHardwareRayTracingCS", SF_Compute);
|
|
IMPLEMENT_GLOBAL_SHADER(FLumenRadianceCacheHardwareRayTracingRGS, "/Engine/Private/Lumen/LumenRadianceCacheHardwareRayTracing.usf", "LumenRadianceCacheHardwareRayTracingRGS", SF_RayGen);
|
|
|
|
class FLumenRadianceCacheHardwareRayTracingIndirectArgsCS : public FGlobalShader
|
|
{
|
|
DECLARE_GLOBAL_SHADER(FLumenRadianceCacheHardwareRayTracingIndirectArgsCS)
|
|
SHADER_USE_PARAMETER_STRUCT(FLumenRadianceCacheHardwareRayTracingIndirectArgsCS, FGlobalShader)
|
|
|
|
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
|
SHADER_PARAMETER_RDG_BUFFER_SRV_ARRAY(Buffer<uint>, CompactedTraceTexelAllocator, [LumenRadianceCache::MaxBatchSize])
|
|
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer<uint>, RWHardwareRayTracingIndirectArgs)
|
|
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer<uint>, RWResolveIndirectArgs)
|
|
SHADER_PARAMETER(FIntPoint, OutputThreadGroupSize)
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
|
|
class FResolveIndirectArgs : SHADER_PERMUTATION_BOOL("RESOLVE_INDIRECT_ARGS");
|
|
class FRadianceCacheBatchSize : SHADER_PERMUTATION_RANGE_INT("RADIANCE_CACHE_BATCH_SIZE", 1, LumenRadianceCache::MaxBatchSize);
|
|
using FPermutationDomain = TShaderPermutationDomain<FResolveIndirectArgs, FRadianceCacheBatchSize>;
|
|
|
|
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(FLumenRadianceCacheHardwareRayTracingIndirectArgsCS, "/Engine/Private/Lumen/LumenRadianceCacheHardwareRayTracing.usf", "LumenRadianceCacheHardwareRayTracingIndirectArgsCS", SF_Compute);
|
|
|
|
class FSplatRadianceCacheIntoAtlasCS : public FGlobalShader
|
|
{
|
|
DECLARE_GLOBAL_SHADER(FSplatRadianceCacheIntoAtlasCS)
|
|
SHADER_USE_PARAMETER_STRUCT(FSplatRadianceCacheIntoAtlasCS, FGlobalShader);
|
|
|
|
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
|
SHADER_PARAMETER_RDG_TEXTURE_UAV_ARRAY(RWTexture2D, RWRadianceProbeAtlasTexture, [LumenRadianceCache::MaxBatchSize])
|
|
SHADER_PARAMETER_RDG_TEXTURE_UAV_ARRAY(RWTexture2D, RWSkyVisibilityProbeAtlasTexture, [LumenRadianceCache::MaxBatchSize])
|
|
SHADER_PARAMETER_RDG_TEXTURE_UAV_ARRAY(RWTexture2D, RWDepthProbeAtlasTexture, [LumenRadianceCache::MaxBatchSize])
|
|
SHADER_PARAMETER_STRUCT_INCLUDE(LumenRadianceCache::FBatchRadianceCacheTracingParameters, BatchTracingParameters)
|
|
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, TraceHitTexture)
|
|
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, TraceRadianceTexture)
|
|
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, TraceSkyVisibilityTexture)
|
|
RDG_BUFFER_ACCESS(ResolveIndirectArgs, ERHIAccess::IndirectArgs)
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
|
|
class FRadianceCacheBatchSize : SHADER_PERMUTATION_RANGE_INT("RADIANCE_CACHE_BATCH_SIZE", 1, LumenRadianceCache::MaxBatchSize);
|
|
class FRadianceCacheSkyVisibility0 : SHADER_PERMUTATION_BOOL("RADIANCE_CACHE_SKY_VISIBILITY_0");
|
|
class FRadianceCacheSkyVisibility1 : SHADER_PERMUTATION_BOOL("RADIANCE_CACHE_SKY_VISIBILITY_1");
|
|
using FPermutationDomain = TShaderPermutationDomain<FRadianceCacheBatchSize, FRadianceCacheSkyVisibility0, FRadianceCacheSkyVisibility1>;
|
|
|
|
static FPermutationDomain RemapPermutation(FPermutationDomain PermutationVector)
|
|
{
|
|
if (PermutationVector.Get<FRadianceCacheBatchSize>() == 1)
|
|
{
|
|
PermutationVector.Set<FRadianceCacheSkyVisibility1>(false);
|
|
}
|
|
|
|
return PermutationVector;
|
|
}
|
|
|
|
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
|
|
{
|
|
FPermutationDomain PermutationVector(Parameters.PermutationId);
|
|
if (RemapPermutation(PermutationVector) != PermutationVector)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return DoesPlatformSupportLumenGI(Parameters.Platform);
|
|
}
|
|
|
|
static uint32 GetGroupSize()
|
|
{
|
|
return LumenRadianceCache::TRACE_TILE_SIZE_2D;
|
|
}
|
|
|
|
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
|
|
{
|
|
FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
|
|
|
|
// 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(FSplatRadianceCacheIntoAtlasCS, "/Engine/Private/Lumen/LumenRadianceCacheHardwareRayTracing.usf", "SplatRadianceCacheIntoAtlasCS", SF_Compute);
|
|
|
|
class FRadianceCacheCompactTracesCS : public FGlobalShader
|
|
{
|
|
DECLARE_GLOBAL_SHADER(FRadianceCacheCompactTracesCS)
|
|
SHADER_USE_PARAMETER_STRUCT(FRadianceCacheCompactTracesCS, FGlobalShader)
|
|
|
|
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
|
RDG_BUFFER_ACCESS(ResolveIndirectArgs, ERHIAccess::IndirectArgs)
|
|
SHADER_PARAMETER_RDG_BUFFER_UAV_ARRAY(RWBuffer<uint>, RWCompactedTraceTexelAllocator, [LumenRadianceCache::MaxBatchSize])
|
|
SHADER_PARAMETER_RDG_BUFFER_UAV_ARRAY(RWBuffer<uint>, RWCompactedTraceTexelData, [LumenRadianceCache::MaxBatchSize])
|
|
SHADER_PARAMETER_STRUCT_INCLUDE(LumenRadianceCache::FBatchRadianceCacheTracingParameters, BatchTracingParameters)
|
|
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, TraceHitTexture)
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
|
|
class FRadianceCacheBatchSize : SHADER_PERMUTATION_RANGE_INT("RADIANCE_CACHE_BATCH_SIZE", 1, LumenRadianceCache::MaxBatchSize);
|
|
using FPermutationDomain = TShaderPermutationDomain<FRadianceCacheBatchSize>;
|
|
|
|
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(FRadianceCacheCompactTracesCS, "/Engine/Private/Lumen/LumenRadianceCacheHardwareRayTracing.usf", "RadianceCacheCompactTracesCS", SF_Compute);
|
|
|
|
bool UseFarFieldForRadianceCache(const FSceneViewFamily& ViewFamily)
|
|
{
|
|
return Lumen::UseFarField(ViewFamily) && CVarLumenRadianceCacheHardwareRayTracingFarField.GetValueOnRenderThread();
|
|
}
|
|
|
|
void FDeferredShadingSceneRenderer::PrepareLumenHardwareRayTracingRadianceCache(const FViewInfo& View, TArray<FRHIRayTracingShader*>& OutRayGenShaders)
|
|
{
|
|
if (Lumen::UseHardwareRayTracedRadianceCache(*View.Family) && LumenRadianceCache::UseHitLighting(View, GetViewPipelineState(View).DiffuseIndirectMethod))
|
|
{
|
|
for (int32 BatchSize = 1; BatchSize <= LumenRadianceCache::MaxBatchSize; ++BatchSize)
|
|
{
|
|
FLumenRadianceCacheHardwareRayTracingRGS::FPermutationDomain PermutationVector;
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FRayTracingPass>(LumenRadianceCache::ERayTracingPass::HitLighting);
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FUseShaderExecutionReordering>(LumenHardwareRayTracing::UseShaderExecutionReordering());
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FSurfaceCacheAlphaMasking>(LumenHardwareRayTracing::UseSurfaceCacheAlphaMasking());
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FFarFieldOcclusionOnly>(false);
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FRadianceCacheSkyVisibility>(LumenScreenProbeGather::UseRadianceCacheSkyVisibility());
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FRadianceCacheBatchSize>(BatchSize);
|
|
PermutationVector = FLumenRadianceCacheHardwareRayTracingRGS::RemapPermutation(PermutationVector);
|
|
|
|
TShaderRef<FLumenRadianceCacheHardwareRayTracingRGS> RayGenerationShader = View.ShaderMap->GetShader<FLumenRadianceCacheHardwareRayTracingRGS>(PermutationVector);
|
|
OutRayGenShaders.Add(RayGenerationShader.GetRayTracingShader());
|
|
}
|
|
}
|
|
}
|
|
|
|
void FDeferredShadingSceneRenderer::PrepareLumenHardwareRayTracingRadianceCacheLumenMaterial(const FViewInfo& View, TArray<FRHIRayTracingShader*>& OutRayGenShaders)
|
|
{
|
|
if (Lumen::UseHardwareRayTracedRadianceCache(*View.Family) && !Lumen::UseHardwareInlineRayTracing(*View.Family))
|
|
{
|
|
for (int32 BatchSize = 1; BatchSize <= LumenRadianceCache::MaxBatchSize; ++BatchSize)
|
|
{
|
|
// Default trace
|
|
{
|
|
FLumenRadianceCacheHardwareRayTracingRGS::FPermutationDomain PermutationVector;
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FRayTracingPass>(LumenRadianceCache::ERayTracingPass::Default);
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FSurfaceCacheAlphaMasking>(LumenHardwareRayTracing::UseSurfaceCacheAlphaMasking());
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FFarFieldOcclusionOnly>(false);
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FRadianceCacheSkyVisibility>(LumenScreenProbeGather::UseRadianceCacheSkyVisibility());
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FRadianceCacheBatchSize>(BatchSize);
|
|
PermutationVector = FLumenRadianceCacheHardwareRayTracingRGS::RemapPermutation(PermutationVector);
|
|
|
|
TShaderRef<FLumenRadianceCacheHardwareRayTracingRGS> RayGenerationShader = View.ShaderMap->GetShader<FLumenRadianceCacheHardwareRayTracingRGS>(PermutationVector);
|
|
|
|
OutRayGenShaders.Add(RayGenerationShader.GetRayTracingShader());
|
|
}
|
|
|
|
if (UseFarFieldForRadianceCache(*View.Family))
|
|
{
|
|
FLumenRadianceCacheHardwareRayTracingRGS::FPermutationDomain PermutationVector;
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FRayTracingPass>(LumenRadianceCache::ERayTracingPass::FarField);
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FSurfaceCacheAlphaMasking>(LumenHardwareRayTracing::UseSurfaceCacheAlphaMasking());
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FFarFieldOcclusionOnly>(Lumen::UseFarFieldOcclusionOnly());
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FRadianceCacheSkyVisibility>(LumenScreenProbeGather::UseRadianceCacheSkyVisibility());
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingRGS::FRadianceCacheBatchSize>(BatchSize);
|
|
PermutationVector = FLumenRadianceCacheHardwareRayTracingRGS::RemapPermutation(PermutationVector);
|
|
|
|
TShaderRef<FLumenRadianceCacheHardwareRayTracingRGS> RayGenerationShader = View.ShaderMap->GetShader<FLumenRadianceCacheHardwareRayTracingRGS>(PermutationVector);
|
|
|
|
OutRayGenShaders.Add(RayGenerationShader.GetRayTracingShader());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DispatchRayGenOrComputeShader(
|
|
FRDGBuilder& GraphBuilder,
|
|
const FScene* Scene,
|
|
const FViewInfo& View,
|
|
const FSceneTextureParameters& SceneTextures,
|
|
const FLumenCardTracingParameters& TracingParameters,
|
|
LumenRadianceCache::FBatchRadianceCacheTracingParameters& BatchTracingParameters,
|
|
const FLumenRadianceCacheHardwareRayTracing::FPermutationDomain& PermutationVector,
|
|
EDiffuseIndirectMethod DiffuseIndirectMethod,
|
|
bool bInlineRayTracing,
|
|
bool bUseFarField,
|
|
FRDGBufferRef HardwareRayTracingIndirectArgsBuffer,
|
|
FRDGTextureRef TraceRadianceTexture,
|
|
FRDGTextureRef TraceSkyVisibilityTexture,
|
|
FRDGTextureRef TraceHitTexture,
|
|
ERDGPassFlags ComputePassFlags)
|
|
{
|
|
FLumenRadianceCacheHardwareRayTracing::FParameters* PassParameters = GraphBuilder.AllocParameters<FLumenRadianceCacheHardwareRayTracing::FParameters>();
|
|
|
|
PassParameters->RWTraceRadianceTexture = GraphBuilder.CreateUAV(TraceRadianceTexture);
|
|
PassParameters->RWTraceSkyVisibilityTexture = TraceSkyVisibilityTexture ? GraphBuilder.CreateUAV(TraceSkyVisibilityTexture) : nullptr;
|
|
PassParameters->RWTraceHitTexture = GraphBuilder.CreateUAV(TraceHitTexture);
|
|
|
|
SetLumenHardwareRayTracingSharedParameters(
|
|
GraphBuilder,
|
|
SceneTextures,
|
|
View,
|
|
TracingParameters,
|
|
&PassParameters->SharedParameters);
|
|
|
|
PassParameters->HardwareRayTracingIndirectArgs = HardwareRayTracingIndirectArgsBuffer;
|
|
PassParameters->BatchTracingParameters = BatchTracingParameters;
|
|
PassParameters->HitLightingForceOpaque = LumenHardwareRayTracing::UseHitLightingForceOpaque();
|
|
PassParameters->HitLightingShadowMode = LumenHardwareRayTracing::GetHitLightingShadowMode();
|
|
PassParameters->HitLightingShadowTranslucencyMode = LumenHardwareRayTracing::GetHitLightingShadowTranslucencyMode();
|
|
PassParameters->HitLightingDirectLighting = LumenHardwareRayTracing::UseHitLightingDirectLighting() ? 1 : 0;
|
|
PassParameters->HitLightingSkylight = LumenHardwareRayTracing::UseHitLightingSkylight(DiffuseIndirectMethod) ? 1 : 0;
|
|
PassParameters->NearFieldMaxTraceDistance = PassParameters->BatchTracingParameters.IndirectTracingParameters.MaxTraceDistance;
|
|
PassParameters->NearFieldSceneRadius = Lumen::GetNearFieldSceneRadius(View, bUseFarField);
|
|
PassParameters->FarFieldBias = LumenHardwareRayTracing::GetFarFieldBias();
|
|
PassParameters->FarFieldMaxTraceDistance = Lumen::GetFarFieldMaxTraceDistance();
|
|
PassParameters->PullbackBias = Lumen::GetHardwareRayTracingPullbackBias();
|
|
|
|
const LumenRadianceCache::ERayTracingPass RayTracingPass = PermutationVector.Get<FLumenRadianceCacheHardwareRayTracing::FRayTracingPass>();
|
|
const FString RayTracingPassName = RayTracingPass == LumenRadianceCache::ERayTracingPass::HitLighting ? TEXT("hit-lighting") : (RayTracingPass == LumenRadianceCache::ERayTracingPass::FarField ? TEXT("far-field") : TEXT("default"));
|
|
|
|
const bool bUseMinimalPayload = RayTracingPass != LumenRadianceCache::ERayTracingPass::HitLighting;
|
|
if (bInlineRayTracing && bUseMinimalPayload)
|
|
{
|
|
// Inline always runs as an indirect compute shader
|
|
FLumenRadianceCacheHardwareRayTracingCS::AddLumenRayTracingDispatchIndirect(
|
|
GraphBuilder,
|
|
RDG_EVENT_NAME("HardwareRayTracingCS %s", *RayTracingPassName),
|
|
View,
|
|
PermutationVector,
|
|
PassParameters,
|
|
PassParameters->HardwareRayTracingIndirectArgs,
|
|
0,
|
|
ComputePassFlags);
|
|
}
|
|
else
|
|
{
|
|
FLumenRadianceCacheHardwareRayTracingRGS::AddLumenRayTracingDispatchIndirect(
|
|
GraphBuilder,
|
|
RDG_EVENT_NAME("HardwareRayTracingRGS %s", *RayTracingPassName),
|
|
View,
|
|
PermutationVector,
|
|
PassParameters,
|
|
PassParameters->HardwareRayTracingIndirectArgs,
|
|
0,
|
|
bUseMinimalPayload,
|
|
ComputePassFlags);
|
|
}
|
|
}
|
|
|
|
#endif // RHI_RAYTRACING
|
|
|
|
extern int32 GRadianceCacheForceFullUpdate;
|
|
|
|
void LumenRadianceCache::RenderLumenHardwareRayTracingRadianceCache(
|
|
FRDGBuilder& GraphBuilder,
|
|
const FScene* Scene,
|
|
const FLumenSceneFrameTemporaries& FrameTemporaries,
|
|
const TInlineArray<FUpdateInputs>& InputArray,
|
|
TInlineArray<FUpdateOutputs>& OutputArray,
|
|
const TInlineArray<FRadianceCacheSetup>& SetupOutputArray,
|
|
const TInlineArray<FRDGBufferRef>& ProbeTraceTileAllocatorArray,
|
|
const TInlineArray<FRDGBufferRef>& ProbeTraceTileDataArray,
|
|
const TInlineArray<FRDGBufferRef>& ProbeTraceDataArray,
|
|
const TInlineArray<FRDGBufferRef>& HardwareRayTracingRayAllocatorBufferArray,
|
|
const TInlineArray<FRDGBufferRef>& TraceProbesIndirectArgsArray,
|
|
ERDGPassFlags ComputePassFlags)
|
|
{
|
|
#if RHI_RAYTRACING
|
|
// Update multiple radiance caches at once in order to overlap work in a common case - single view with an opaque and an translucent radiance cache
|
|
// Normal draw overlap doesn't work with our D3D12 RHI, so need to do it manually inside every dispatch
|
|
for (int32 BaseRadianceCacheIndex = 0; BaseRadianceCacheIndex < InputArray.Num(); BaseRadianceCacheIndex += LumenRadianceCache::MaxBatchSize)
|
|
{
|
|
const FViewInfo& View = InputArray[BaseRadianceCacheIndex].View;
|
|
const FSceneTextureParameters& SceneTextures = GetSceneTextureParameters(GraphBuilder, View);
|
|
const uint32 BatchSize = FMath::Min(LumenRadianceCache::MaxBatchSize, InputArray.Num() - BaseRadianceCacheIndex);
|
|
const EDiffuseIndirectMethod DiffuseIndirectMethod = EDiffuseIndirectMethod::Lumen;
|
|
|
|
// Compute temporary atlas size
|
|
// Overflow is possible however unlikely - only nearby probes trace at max resolution
|
|
int32 TempAtlasNumTraceTiles = 0;
|
|
const int32 TemporaryBufferAllocationDownsampleFactor = GRadianceCacheForceFullUpdate ? 4 : CVarLumenRadianceCacheTemporaryBufferAllocationDownsampleFactor.GetValueOnRenderThread();
|
|
for (uint32 IndexInBatch = 0; IndexInBatch < BatchSize; ++IndexInBatch)
|
|
{
|
|
const FUpdateInputs& Inputs = InputArray[BaseRadianceCacheIndex + IndexInBatch];
|
|
const FRadianceCacheInputs& RadianceCacheInputs = Inputs.RadianceCacheInputs;
|
|
|
|
const int32 MaxProbeTraceTileResolution = RadianceCacheInputs.RadianceProbeResolution / LumenRadianceCache::TRACE_TILE_SIZE_2D * 2;
|
|
const int32 MaxNumProbes = RadianceCacheInputs.ProbeAtlasResolutionInProbes.X * RadianceCacheInputs.ProbeAtlasResolutionInProbes.Y;
|
|
const int32 TempAtlasNumTraceTilesPerProbe = FMath::DivideAndRoundUp(MaxProbeTraceTileResolution * MaxProbeTraceTileResolution, TemporaryBufferAllocationDownsampleFactor);
|
|
TempAtlasNumTraceTiles += MaxNumProbes * TempAtlasNumTraceTilesPerProbe;
|
|
}
|
|
|
|
FLumenCardTracingParameters TracingParameters;
|
|
GetLumenCardTracingParameters(GraphBuilder, View, *Scene->GetLumenSceneData(View), FrameTemporaries, /*bSurfaceCacheFeedback*/ false, TracingParameters);
|
|
|
|
LumenRadianceCache::FBatchRadianceCacheTracingParameters BatchTracingParameters;
|
|
SetupLumenDiffuseTracingParametersForProbe(View, BatchTracingParameters.IndirectTracingParameters, /*DiffuseConeHalfAngle*/ -1.0f);
|
|
BatchTracingParameters.TempAtlasNumTraceTiles = TempAtlasNumTraceTiles;
|
|
|
|
bool bUseFarField = false;
|
|
bool bSkyVisibility0 = InputArray[BaseRadianceCacheIndex + 0].Configuration.bSkyVisibility;
|
|
bool bSkyVisibility1 = BatchSize > 1 && InputArray[BaseRadianceCacheIndex + 1].Configuration.bSkyVisibility;
|
|
|
|
for (uint32 IndexInBatch = 0; IndexInBatch < BatchSize; ++IndexInBatch)
|
|
{
|
|
const uint32 RadianceCacheIndex = BaseRadianceCacheIndex + IndexInBatch;
|
|
|
|
FRadianceCacheTracingParameters& RadianceCacheParameters = BatchTracingParameters.RadianceCache[RadianceCacheIndex];
|
|
RadianceCacheParameters.ProbeTraceData = GraphBuilder.CreateSRV(ProbeTraceDataArray[RadianceCacheIndex], PF_A32B32G32R32F);
|
|
RadianceCacheParameters.CompactedTraceTexelAllocator = GraphBuilder.CreateSRV(HardwareRayTracingRayAllocatorBufferArray[RadianceCacheIndex], PF_R32_UINT);
|
|
RadianceCacheParameters.CompactedTraceTexelData = nullptr;
|
|
RadianceCacheParameters.ProbeTraceTileAllocator = GraphBuilder.CreateSRV(ProbeTraceTileAllocatorArray[RadianceCacheIndex], PF_R32_UINT);
|
|
RadianceCacheParameters.ProbeTraceTileData = GraphBuilder.CreateSRV(ProbeTraceTileDataArray[RadianceCacheIndex], PF_R32G32_UINT);
|
|
|
|
const FUpdateInputs& Inputs = InputArray[RadianceCacheIndex];
|
|
const FUpdateOutputs& Outputs = OutputArray[RadianceCacheIndex];
|
|
const FRadianceCacheInterpolationParameters& InterpolationParameters = Outputs.RadianceCacheParameters;
|
|
RadianceCacheParameters.ProbeAtlasResolutionModuloMask = InterpolationParameters.ProbeAtlasResolutionModuloMask;
|
|
RadianceCacheParameters.ProbeAtlasResolutionDivideShift = InterpolationParameters.ProbeAtlasResolutionDivideShift;
|
|
RadianceCacheParameters.RadianceProbeResolution = Inputs.RadianceCacheInputs.RadianceProbeResolution;
|
|
RadianceCacheParameters.FarField = 0;
|
|
RadianceCacheParameters.SkyVisibility = Inputs.Configuration.bSkyVisibility ? 1 : 0;
|
|
|
|
if (UseFarFieldForRadianceCache(*View.Family) && Inputs.Configuration.bFarField)
|
|
{
|
|
RadianceCacheParameters.FarField = 1;
|
|
bUseFarField = true;
|
|
}
|
|
|
|
for (uint32 ClipmapIndex = 0; ClipmapIndex < LumenRadianceCache::MaxClipmaps; ++ClipmapIndex)
|
|
{
|
|
RadianceCacheParameters.RadianceProbeSettings[ClipmapIndex] = InterpolationParameters.RadianceProbeSettings[ClipmapIndex];
|
|
}
|
|
}
|
|
|
|
const FIntPoint WrappedTraceTileLayout(
|
|
LumenRadianceCache::TRACE_TILE_ATLAS_STRITE_IN_TILES,
|
|
FMath::DivideAndRoundUp(TempAtlasNumTraceTiles, LumenRadianceCache::TRACE_TILE_ATLAS_STRITE_IN_TILES));
|
|
const FIntPoint TempTraceAtlasResolution = WrappedTraceTileLayout * LumenRadianceCache::TRACE_TILE_SIZE_2D;
|
|
const EPixelFormat TraceRadianceTextureFormat = Lumen::GetLightingDataFormat();
|
|
|
|
FRDGTextureRef TraceRadianceTexture = GraphBuilder.CreateTexture(
|
|
FRDGTextureDesc::Create2D(TempTraceAtlasResolution, TraceRadianceTextureFormat, FClearValueBinding::Black, TexCreate_ShaderResource | TexCreate_UAV),
|
|
TEXT("Lumen.RadianceCache.TraceRadiance"));
|
|
|
|
FRDGTextureRef TraceSkyVisibilityTexture = nullptr;
|
|
if (bSkyVisibility0 || bSkyVisibility1)
|
|
{
|
|
TraceSkyVisibilityTexture = GraphBuilder.CreateTexture(
|
|
FRDGTextureDesc::Create2D(TempTraceAtlasResolution, TraceRadianceTextureFormat, FClearValueBinding::Black, TexCreate_ShaderResource | TexCreate_UAV),
|
|
TEXT("Lumen.RadianceCache.TraceSkyVisibility"));
|
|
}
|
|
|
|
FRDGTextureRef TraceHitTexture = GraphBuilder.CreateTexture(
|
|
FRDGTextureDesc::Create2D(TempTraceAtlasResolution, PF_R16F, FClearValueBinding::Black, TexCreate_ShaderResource | TexCreate_UAV),
|
|
TEXT("Lumen.RadianceCache.TraceHit"));
|
|
|
|
const bool bUseHitLighting = LumenRadianceCache::UseHitLighting(View, DiffuseIndirectMethod);
|
|
const bool bInlineRayTracing = Lumen::UseHardwareInlineRayTracing(*View.Family) && !bUseHitLighting;
|
|
|
|
// Setup indirect parameters
|
|
FRDGBufferRef HardwareRayTracingIndirectArgsBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateIndirectDesc<FRHIDispatchIndirectParameters>(1), TEXT("Lumen.RadianceCache.HardwareRayTracing.IndirectArgsBuffer"));
|
|
FRDGBufferRef ResolveIndirectArgs = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateIndirectDesc<FRHIDispatchIndirectParameters>(1), TEXT("Lumen.RadianceCache.HardwareRayTracing.ResolveIndirectArgs"));
|
|
{
|
|
FLumenRadianceCacheHardwareRayTracingIndirectArgsCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FLumenRadianceCacheHardwareRayTracingIndirectArgsCS::FParameters>();
|
|
for (uint32 IndexInBatch = 0; IndexInBatch < BatchSize; ++IndexInBatch)
|
|
{
|
|
PassParameters->CompactedTraceTexelAllocator[IndexInBatch] = BatchTracingParameters.RadianceCache[IndexInBatch].CompactedTraceTexelAllocator;
|
|
}
|
|
PassParameters->RWHardwareRayTracingIndirectArgs = GraphBuilder.CreateUAV(HardwareRayTracingIndirectArgsBuffer);
|
|
PassParameters->RWResolveIndirectArgs = GraphBuilder.CreateUAV(ResolveIndirectArgs);
|
|
PassParameters->OutputThreadGroupSize = bInlineRayTracing && !bUseHitLighting ? FLumenRadianceCacheHardwareRayTracingCS::GetThreadGroupSize(View.GetShaderPlatform()) : FLumenRadianceCacheHardwareRayTracingRGS::GetThreadGroupSize();
|
|
|
|
FLumenRadianceCacheHardwareRayTracingIndirectArgsCS::FPermutationDomain PermutationVector;
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingIndirectArgsCS::FResolveIndirectArgs>(true);
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingIndirectArgsCS::FRadianceCacheBatchSize>(BatchSize);
|
|
TShaderRef<FLumenRadianceCacheHardwareRayTracingIndirectArgsCS> ComputeShader = View.ShaderMap->GetShader<FLumenRadianceCacheHardwareRayTracingIndirectArgsCS>(PermutationVector);
|
|
|
|
FComputeShaderUtils::AddPass(
|
|
GraphBuilder,
|
|
RDG_EVENT_NAME("HardwareRayTracingIndirectArgs BatchSize:%d", BatchSize),
|
|
ComputePassFlags,
|
|
ComputeShader,
|
|
PassParameters,
|
|
FIntVector(1, 1, 1));
|
|
}
|
|
|
|
// Default tracing of near-field
|
|
{
|
|
FLumenRadianceCacheHardwareRayTracing::FPermutationDomain PermutationVector;
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracing::FRayTracingPass>(bUseHitLighting ? ERayTracingPass::HitLighting : ERayTracingPass::Default);
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracing::FUseShaderExecutionReordering>(bUseHitLighting && LumenHardwareRayTracing::UseShaderExecutionReordering());
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracing::FSurfaceCacheAlphaMasking>(LumenHardwareRayTracing::UseSurfaceCacheAlphaMasking());
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracing::FFarFieldOcclusionOnly>(false);
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracing::FRadianceCacheSkyVisibility>(bSkyVisibility0 || bSkyVisibility1);
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracing::FRadianceCacheBatchSize>(BatchSize);
|
|
PermutationVector = FLumenRadianceCacheHardwareRayTracing::RemapPermutation(PermutationVector);
|
|
|
|
DispatchRayGenOrComputeShader(
|
|
GraphBuilder,
|
|
Scene,
|
|
View,
|
|
SceneTextures,
|
|
TracingParameters,
|
|
BatchTracingParameters,
|
|
PermutationVector,
|
|
DiffuseIndirectMethod,
|
|
bInlineRayTracing,
|
|
bUseFarField,
|
|
HardwareRayTracingIndirectArgsBuffer,
|
|
TraceRadianceTexture,
|
|
TraceSkyVisibilityTexture,
|
|
TraceHitTexture,
|
|
ComputePassFlags);
|
|
}
|
|
|
|
if (bUseFarField)
|
|
{
|
|
TInlineArray<FRDGBufferRef> CompactedTraceTexelAllocatorArray(BatchSize);
|
|
TInlineArray<FRDGBufferRef> CompactedTraceTexelDataArray(BatchSize);
|
|
|
|
for (uint32 IndexInBatch = 0; IndexInBatch < BatchSize; ++IndexInBatch)
|
|
{
|
|
CompactedTraceTexelAllocatorArray[IndexInBatch] = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), 2), TEXT("Lumen.RadianceCache.CompactedTraceTexelAllocator"));;
|
|
AddClearUAVPass(GraphBuilder, GraphBuilder.CreateUAV(CompactedTraceTexelAllocatorArray[IndexInBatch], PF_R32_UINT), 0, ComputePassFlags);
|
|
|
|
const int32 NumCompactedTraceTexelDataElements = TempTraceAtlasResolution.X * TempTraceAtlasResolution.Y;
|
|
CompactedTraceTexelDataArray[IndexInBatch] = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), NumCompactedTraceTexelDataElements), TEXT("Lumen.RadianceCache.CompactedTraceTexelData"));
|
|
}
|
|
|
|
// Compact unfinished traces
|
|
{
|
|
FRadianceCacheCompactTracesCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FRadianceCacheCompactTracesCS::FParameters>();
|
|
for (uint32 IndexInBatch = 0; IndexInBatch < BatchSize; ++IndexInBatch)
|
|
{
|
|
PassParameters->RWCompactedTraceTexelAllocator[IndexInBatch] = GraphBuilder.CreateUAV(CompactedTraceTexelAllocatorArray[IndexInBatch], PF_R32_UINT);
|
|
PassParameters->RWCompactedTraceTexelData[IndexInBatch] = GraphBuilder.CreateUAV(CompactedTraceTexelDataArray[IndexInBatch], PF_R32_UINT);
|
|
}
|
|
PassParameters->ResolveIndirectArgs = ResolveIndirectArgs;
|
|
PassParameters->BatchTracingParameters = BatchTracingParameters;
|
|
PassParameters->TraceHitTexture = TraceHitTexture;
|
|
|
|
FRadianceCacheCompactTracesCS::FPermutationDomain PermutationVector;
|
|
PermutationVector.Set<FRadianceCacheCompactTracesCS::FRadianceCacheBatchSize>(BatchSize);
|
|
auto ComputeShader = View.ShaderMap->GetShader<FRadianceCacheCompactTracesCS>(PermutationVector);
|
|
|
|
FComputeShaderUtils::AddPass(
|
|
GraphBuilder,
|
|
RDG_EVENT_NAME("CompactTraces"),
|
|
ComputePassFlags,
|
|
ComputeShader,
|
|
PassParameters,
|
|
PassParameters->ResolveIndirectArgs,
|
|
0);
|
|
}
|
|
|
|
// Setup indirect parameters for the Far Field re-trace
|
|
{
|
|
FLumenRadianceCacheHardwareRayTracingIndirectArgsCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FLumenRadianceCacheHardwareRayTracingIndirectArgsCS::FParameters>();
|
|
for (uint32 IndexInBatch = 0; IndexInBatch < BatchSize; ++IndexInBatch)
|
|
{
|
|
FRadianceCacheTracingParameters& RadianceCache = BatchTracingParameters.RadianceCache[IndexInBatch];
|
|
RadianceCache.CompactedTraceTexelAllocator = GraphBuilder.CreateSRV(CompactedTraceTexelAllocatorArray[IndexInBatch], PF_R32_UINT);
|
|
RadianceCache.CompactedTraceTexelData = GraphBuilder.CreateSRV(CompactedTraceTexelDataArray[IndexInBatch], PF_R32_UINT);
|
|
|
|
PassParameters->CompactedTraceTexelAllocator[IndexInBatch] = RadianceCache.CompactedTraceTexelAllocator;
|
|
}
|
|
PassParameters->RWHardwareRayTracingIndirectArgs = GraphBuilder.CreateUAV(HardwareRayTracingIndirectArgsBuffer);
|
|
PassParameters->RWResolveIndirectArgs = nullptr;
|
|
PassParameters->OutputThreadGroupSize = bInlineRayTracing && !bUseHitLighting ? FLumenRadianceCacheHardwareRayTracingCS::GetThreadGroupSize(View.GetShaderPlatform()) : FLumenRadianceCacheHardwareRayTracingRGS::GetThreadGroupSize();
|
|
|
|
FLumenRadianceCacheHardwareRayTracingIndirectArgsCS::FPermutationDomain PermutationVector;
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingIndirectArgsCS::FResolveIndirectArgs>(false);
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracingIndirectArgsCS::FRadianceCacheBatchSize>(BatchSize);
|
|
TShaderRef<FLumenRadianceCacheHardwareRayTracingIndirectArgsCS> ComputeShader = View.ShaderMap->GetShader<FLumenRadianceCacheHardwareRayTracingIndirectArgsCS>(PermutationVector);
|
|
|
|
FComputeShaderUtils::AddPass(
|
|
GraphBuilder,
|
|
RDG_EVENT_NAME("HardwareRayTracingIndirectArgs FarField BatchSize:%d", BatchSize),
|
|
ComputePassFlags,
|
|
ComputeShader,
|
|
PassParameters,
|
|
FIntVector(1, 1, 1));
|
|
}
|
|
|
|
FLumenRadianceCacheHardwareRayTracing::FPermutationDomain PermutationVector;
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracing::FRayTracingPass>(ERayTracingPass::FarField);
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracing::FSurfaceCacheAlphaMasking>(LumenHardwareRayTracing::UseSurfaceCacheAlphaMasking());
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracing::FFarFieldOcclusionOnly>(Lumen::UseFarFieldOcclusionOnly());
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracing::FRadianceCacheSkyVisibility>(bSkyVisibility0 || bSkyVisibility1);
|
|
PermutationVector.Set<FLumenRadianceCacheHardwareRayTracing::FRadianceCacheBatchSize>(BatchSize);
|
|
PermutationVector = FLumenRadianceCacheHardwareRayTracing::RemapPermutation(PermutationVector);
|
|
|
|
DispatchRayGenOrComputeShader(
|
|
GraphBuilder,
|
|
Scene,
|
|
View,
|
|
SceneTextures,
|
|
TracingParameters,
|
|
BatchTracingParameters,
|
|
PermutationVector,
|
|
DiffuseIndirectMethod,
|
|
bInlineRayTracing,
|
|
bUseFarField,
|
|
HardwareRayTracingIndirectArgsBuffer,
|
|
TraceRadianceTexture,
|
|
TraceSkyVisibilityTexture,
|
|
TraceHitTexture,
|
|
ComputePassFlags);
|
|
}
|
|
|
|
// Write temporary results to atlas, possibly up-sampling
|
|
{
|
|
FSplatRadianceCacheIntoAtlasCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FSplatRadianceCacheIntoAtlasCS::FParameters>();
|
|
PassParameters->ResolveIndirectArgs = ResolveIndirectArgs;
|
|
for (uint32 IndexInBatch = 0; IndexInBatch < BatchSize; ++IndexInBatch)
|
|
{
|
|
const FRadianceCacheSetup& Setup = SetupOutputArray[BaseRadianceCacheIndex + IndexInBatch];
|
|
PassParameters->RWRadianceProbeAtlasTexture[IndexInBatch] = GraphBuilder.CreateUAV(Setup.RadianceProbeAtlasTextureSource);
|
|
PassParameters->RWSkyVisibilityProbeAtlasTexture[IndexInBatch] = Setup.SkyVisibilityProbeAtlasTextureSource ? GraphBuilder.CreateUAV(Setup.SkyVisibilityProbeAtlasTextureSource) : nullptr;
|
|
PassParameters->RWDepthProbeAtlasTexture[IndexInBatch] = GraphBuilder.CreateUAV(Setup.DepthProbeAtlasTexture);
|
|
}
|
|
PassParameters->BatchTracingParameters = BatchTracingParameters;
|
|
PassParameters->TraceRadianceTexture = TraceRadianceTexture;
|
|
PassParameters->TraceSkyVisibilityTexture = TraceSkyVisibilityTexture;
|
|
PassParameters->TraceHitTexture = TraceHitTexture;
|
|
|
|
FSplatRadianceCacheIntoAtlasCS::FPermutationDomain PermutationVector;
|
|
PermutationVector.Set<FSplatRadianceCacheIntoAtlasCS::FRadianceCacheBatchSize>(BatchSize);
|
|
PermutationVector.Set<FSplatRadianceCacheIntoAtlasCS::FRadianceCacheSkyVisibility0>(bSkyVisibility0);
|
|
PermutationVector.Set<FSplatRadianceCacheIntoAtlasCS::FRadianceCacheSkyVisibility1>(bSkyVisibility1);
|
|
PermutationVector = FSplatRadianceCacheIntoAtlasCS::RemapPermutation(PermutationVector);
|
|
auto ComputeShader = View.ShaderMap->GetShader<FSplatRadianceCacheIntoAtlasCS>(PermutationVector);
|
|
|
|
FComputeShaderUtils::AddPass(
|
|
GraphBuilder,
|
|
RDG_EVENT_NAME("CompositeTracesIntoAtlas"),
|
|
ComputePassFlags,
|
|
ComputeShader,
|
|
PassParameters,
|
|
PassParameters->ResolveIndirectArgs,
|
|
0);
|
|
}
|
|
}
|
|
#else
|
|
unimplemented();
|
|
#endif // RHI_RAYTRACING
|
|
} |