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

903 lines
42 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "LumenVisualize.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 "SceneTextureParameters.h"
#include "IndirectLightRendering.h"
#include "LumenReflections.h"
#include "HairStrands/HairStrandsData.h"
#include "LumenRadianceCache.h"
#include "LumenScreenProbeGather.h"
#include "LumenHardwareRayTracingCommon.h"
#include "RayTracing/RayTracing.h"
#if RHI_RAYTRACING
#include "RayTracing/RaytracingOptions.h"
#include "RayTracing/RayTracingLighting.h"
#endif // RHI_RAYTRACING
static TAutoConsoleVariable<int32> CVarLumenVisualizeHardwareRayTracing(
TEXT("r.Lumen.Visualize.HardwareRayTracing"),
1,
TEXT("Enables visualization of hardware ray tracing (Default = 1)"),
ECVF_RenderThreadSafe
);
static TAutoConsoleVariable<int32> CVarLumenVisualizeHardwareRayTracingDeferredMaterial(
TEXT("r.Lumen.Visualize.HardwareRayTracing.DeferredMaterial"),
1,
TEXT("Enables deferred material pipeline (Default = 1)"),
ECVF_RenderThreadSafe
);
static TAutoConsoleVariable<int32> CVarLumenVisualizeHardwareRayTracingDeferredMaterialTileSize(
TEXT("r.Lumen.Visualize.HardwareRayTracing.DeferredMaterial.TileDimension"),
64,
TEXT("Determines the tile dimension for material sorting (Default = 64)"),
ECVF_RenderThreadSafe
);
static TAutoConsoleVariable<int32> CVarLumenVisualizeHardwareRayTracingThreadCount(
TEXT("r.Lumen.Visualize.HardwareRayTracing.ThreadCount"),
64,
TEXT("Determines the active group count when dispatching raygen shader (default = 64"),
ECVF_RenderThreadSafe
);
static TAutoConsoleVariable<int32> CVarLumenVisualizeHardwareRayTracingGroupCount(
TEXT("r.Lumen.Visualize.HardwareRayTracing.GroupCount"),
4096,
TEXT("Determines the active group count when dispatching raygen shader (default = 4096"),
ECVF_RenderThreadSafe
);
static TAutoConsoleVariable<int32> CVarLumenVisualizeHardwareRayTracingHitLighting(
TEXT("r.Lumen.Visualize.HardwareRayTracing.HitLighting"),
0,
TEXT("Determines whether a second trace will be fired for hit-lighting for invalid surface-cache hits (default = 1"),
ECVF_RenderThreadSafe
);
static TAutoConsoleVariable<int32> CVarLumenVisualizeHardwareRayTracingFarField(
TEXT("r.Lumen.Visualize.HardwareRayTracing.FarField"),
1,
TEXT("Determines whether a second trace will be fired for far-field contribution (default = 1"),
ECVF_RenderThreadSafe
);
static TAutoConsoleVariable<int32> CVarLumenVisualizeHardwareRayTracingCompact(
TEXT("r.Lumen.Visualize.HardwareRayTracing.Compact"),
1,
TEXT("Determines whether a second trace will be compacted before traversal (default = 1"),
ECVF_RenderThreadSafe
);
static TAutoConsoleVariable<int32> CVarLumenVisualizeHardwareRayTracingBucketMaterials(
TEXT("r.Lumen.Visualize.HardwareRayTracing.BucketMaterials"),
1,
TEXT("Determines whether a secondary traces will be bucketed for coherent material access (default = 1"),
ECVF_RenderThreadSafe
);
namespace Lumen
{
bool UseHardwareRayTracedVisualize(const FSceneViewFamily& ViewFamily)
{
bool bVisualize = false;
#if RHI_RAYTRACING
bVisualize = IsRayTracingEnabled()
&& Lumen::UseHardwareRayTracing(ViewFamily)
&& CVarLumenVisualizeHardwareRayTracing.GetValueOnRenderThread() != 0;
#endif
return bVisualize;
}
bool ShouldVisualizeHardwareRayTracing(const FSceneViewFamily& ViewFamily)
{
return UseHardwareRayTracedVisualize(ViewFamily) && Lumen::ShouldVisualizeScene(ViewFamily.EngineShowFlags);
}
} // namespace Lumen
namespace LumenVisualize
{
bool UseFarField(const FSceneViewFamily& ViewFamily)
{
return Lumen::UseFarField(ViewFamily) && CVarLumenVisualizeHardwareRayTracingFarField.GetValueOnRenderThread() != 0;
}
bool IsHitLightingForceEnabled(const FViewInfo& View, EDiffuseIndirectMethod DiffuseIndirectMethod)
{
return LumenHardwareRayTracing::GetHitLightingMode(View, DiffuseIndirectMethod) != LumenHardwareRayTracing::EHitLightingMode::SurfaceCache;
}
bool UseHitLighting(const FViewInfo& View, EDiffuseIndirectMethod DiffuseIndirectMethod)
{
if (LumenHardwareRayTracing::IsRayGenSupported())
{
return LumenVisualize::IsHitLightingForceEnabled(View, DiffuseIndirectMethod)
|| CVarLumenVisualizeHardwareRayTracingHitLighting.GetValueOnRenderThread() != 0;
}
return false;
}
}
#if RHI_RAYTRACING
namespace LumenVisualize
{
// Struct definitions much match those in LumenVisualizeHardwareRayTracing.usf
struct FTileDataPacked
{
uint32 PackedData;
};
struct FRayDataPacked
{
uint32 PackedData;
};
struct FTraceDataPacked
{
uint32 PackedData[2];
};
enum class ECompactMode
{
// Permutations for compaction modes
HitLightingRetrace,
ForceHitLighting,
MAX
};
} // namespace LumenVisualize
class FLumenVisualizeCreateTilesCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FLumenVisualizeCreateTilesCS)
SHADER_USE_PARAMETER_STRUCT(FLumenVisualizeCreateTilesCS, FGlobalShader);
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
// Input
SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, View)
SHADER_PARAMETER_STRUCT_INCLUDE(LumenVisualize::FSceneParameters, VisualizeParameters)
// Output
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer<uint>, RWTileAllocator)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<FTileData>, RWTileDataPacked)
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("ENABLE_VISUALIZE_MODE"), 1);
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_1D"), GetThreadGroupSize1D());
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_2D"), GetThreadGroupSize2D());
}
static int32 GetThreadGroupSize1D() { return GetThreadGroupSize2D() * GetThreadGroupSize2D(); }
static int32 GetThreadGroupSize2D() { return 8; }
};
IMPLEMENT_GLOBAL_SHADER(FLumenVisualizeCreateTilesCS, "/Engine/Private/Lumen/LumenVisualizeHardwareRayTracing.usf", "FLumenVisualizeCreateTilesCS", SF_Compute);
const int32 VisualizeCreateRaysDispatchSizeX = 128;
class FLumenVisualizeCreateRaysCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FLumenVisualizeCreateRaysCS)
SHADER_USE_PARAMETER_STRUCT(FLumenVisualizeCreateRaysCS, FGlobalShader);
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
// Input
SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, View)
SHADER_PARAMETER_STRUCT_INCLUDE(FSceneTextureParameters, SceneTextures)
SHADER_PARAMETER_STRUCT_INCLUDE(LumenVisualize::FSceneParameters, VisualizeParameters)
SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer<uint>, TileAllocator)
SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<LumenVisualize::FTileDataPacked>, TileDataPacked)
SHADER_PARAMETER(float, MaxTraceDistance)
// Output
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer<uint>, RWRayAllocator)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<LumenVisualize::FRayDataPacked>, RWRayDataPacked)
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("ENABLE_VISUALIZE_MODE"), 1);
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_1D"), GetThreadGroupSize1D());
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_2D"), GetThreadGroupSize2D());
OutEnvironment.SetDefine(TEXT("DISPATCH_GROUP_SIZE_X"), VisualizeCreateRaysDispatchSizeX);
}
static int32 GetThreadGroupSize1D() { return GetThreadGroupSize2D() * GetThreadGroupSize2D(); }
static int32 GetThreadGroupSize2D() { return 8; }
};
IMPLEMENT_GLOBAL_SHADER(FLumenVisualizeCreateRaysCS, "/Engine/Private/Lumen/LumenVisualizeHardwareRayTracing.usf", "FLumenVisualizeCreateRaysCS", SF_Compute);
class FLumenVisualizeCompactRaysIndirectArgsCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FLumenVisualizeCompactRaysIndirectArgsCS)
SHADER_USE_PARAMETER_STRUCT(FLumenVisualizeCompactRaysIndirectArgsCS, FGlobalShader)
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer<uint>, RayAllocator)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer<uint>, RWCompactRaysIndirectArgs)
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("ENABLE_VISUALIZE_MODE"), 1);
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_1D"), GetThreadGroupSize1D());
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_2D"), GetThreadGroupSize2D());
}
static int32 GetThreadGroupSize1D() { return GetThreadGroupSize2D() * GetThreadGroupSize2D(); }
static int32 GetThreadGroupSize2D() { return 8; }
};
IMPLEMENT_GLOBAL_SHADER(FLumenVisualizeCompactRaysIndirectArgsCS, "/Engine/Private/Lumen/LumenVisualizeHardwareRayTracing.usf", "FLumenVisualizeCompactRaysIndirectArgsCS", SF_Compute);
class FLumenVisualizeCompactRaysCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FLumenVisualizeCompactRaysCS)
SHADER_USE_PARAMETER_STRUCT(FLumenVisualizeCompactRaysCS, FGlobalShader);
class FCompactModeDim : SHADER_PERMUTATION_ENUM_CLASS("DIM_COMPACT_MODE", LumenVisualize::ECompactMode);
using FPermutationDomain = TShaderPermutationDomain<FCompactModeDim>;
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
// Input
SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer<uint>, RayAllocator)
SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<LumenVisualize::FRayDataPacked>, RayDataPacked)
SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<LumenVisualize::FTraceDataPacked>, TraceDataPacked)
SHADER_PARAMETER(int, MaxRayAllocationCount)
// Output
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer<uint>, RWCompactedRayAllocator)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<LumenVisualize::FRayDataPacked>, RWCompactedRayDataPacked)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<LumenVisualize::FTraceDataPacked>, RWCompactedTraceDataPacked)
// Indirect
RDG_BUFFER_ACCESS(CompactRaysIndirectArgs, ERHIAccess::IndirectArgs)
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("ENABLE_VISUALIZE_MODE"), 1);
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_1D"), GetThreadGroupSize1D());
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_2D"), GetThreadGroupSize2D());
}
static int32 GetThreadGroupSize1D() { return GetThreadGroupSize2D() * GetThreadGroupSize2D(); }
static int32 GetThreadGroupSize2D() { return 8; }
};
IMPLEMENT_GLOBAL_SHADER(FLumenVisualizeCompactRaysCS, "/Engine/Private/Lumen/LumenVisualizeHardwareRayTracing.usf", "FLumenVisualizeCompactRaysCS", SF_Compute);
class FLumenVisualizeBucketRaysByMaterialIdIndirectArgsCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FLumenVisualizeBucketRaysByMaterialIdIndirectArgsCS)
SHADER_USE_PARAMETER_STRUCT(FLumenVisualizeBucketRaysByMaterialIdIndirectArgsCS, FGlobalShader)
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer<uint>, RayAllocator)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWBuffer<uint>, RWBucketRaysByMaterialIdIndirectArgs)
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("ENABLE_VISUALIZE_MODE"), 1);
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_1D"), GetThreadGroupSize1D());
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_2D"), GetThreadGroupSize2D());
}
static int32 GetThreadGroupSize1D() { return GetThreadGroupSize2D() * GetThreadGroupSize2D(); }
static int32 GetThreadGroupSize2D() { return 16; }
};
IMPLEMENT_GLOBAL_SHADER(FLumenVisualizeBucketRaysByMaterialIdIndirectArgsCS, "/Engine/Private/Lumen/LumenVisualizeHardwareRayTracing.usf", "FLumenVisualizeBucketRaysByMaterialIdIndirectArgsCS", SF_Compute);
class FLumenVisualizeBucketRaysByMaterialIdCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FLumenVisualizeBucketRaysByMaterialIdCS)
SHADER_USE_PARAMETER_STRUCT(FLumenVisualizeBucketRaysByMaterialIdCS, FGlobalShader);
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
// Input
SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer<uint>, RayAllocator)
SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<LumenVisualize::FRayDataPacked>, RayDataPacked)
SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<LumenVisualize::FTraceDataPacked>, TraceDataPacked)
SHADER_PARAMETER(int, MaxRayAllocationCount)
// Output
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<LumenVisualize::FRayDataPacked>, RWRayDataPacked)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<LumenVisualize::FTraceDataPacked>, RWTraceDataPacked)
// Indirect args
RDG_BUFFER_ACCESS(BucketRaysByMaterialIdIndirectArgs, ERHIAccess::IndirectArgs)
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("ENABLE_VISUALIZE_MODE"), 1);
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_1D"), GetThreadGroupSize1D());
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_2D"), GetThreadGroupSize2D());
}
static int32 GetThreadGroupSize1D() { return GetThreadGroupSize2D() * GetThreadGroupSize2D(); }
static int32 GetThreadGroupSize2D() { return 16; }
};
IMPLEMENT_GLOBAL_SHADER(FLumenVisualizeBucketRaysByMaterialIdCS, "/Engine/Private/Lumen/LumenVisualizeHardwareRayTracing.usf", "FLumenVisualizeBucketRaysByMaterialIdCS", SF_Compute);
class FLumenVisualizeHardwareRayTracing : public FLumenHardwareRayTracingShaderBase
{
DECLARE_LUMEN_RAYTRACING_SHADER(FLumenVisualizeHardwareRayTracing)
class FHitLightingDim : SHADER_PERMUTATION_BOOL("DIM_HIT_LIGHTING");
class FHairStrandsOcclusionDim : SHADER_PERMUTATION_BOOL("DIM_HAIRSTRANDS_VOXEL");
class FFarFieldDim : SHADER_PERMUTATION_BOOL("ENABLE_FAR_FIELD_TRACING");
class FRecursiveRefractionTraces : SHADER_PERMUTATION_BOOL("RECURSIVE_REFRACTION_TRACES");
class FSurfaceCacheAlphaMasking : SHADER_PERMUTATION_BOOL("SURFACE_CACHE_ALPHA_MASKING");
using FPermutationDomain = TShaderPermutationDomain<FLumenHardwareRayTracingShaderBase::FBasePermutationDomain, FHitLightingDim, FHairStrandsOcclusionDim, FFarFieldDim, FRecursiveRefractionTraces, FSurfaceCacheAlphaMasking>;
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
// Input
SHADER_PARAMETER_STRUCT_INCLUDE(FLumenHardwareRayTracingShaderBase::FSharedParameters, SharedParameters)
SHADER_PARAMETER_STRUCT_INCLUDE(LumenVisualize::FSceneParameters, VisualizeParameters)
SHADER_PARAMETER_RDG_BUFFER_SRV(Buffer<uint>, RayAllocator)
SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<LumenVisualize::FRayDataPacked>, RayDataPacked)
SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<LumenVisualize::FTraceDataPacked>, TraceDataPacked)
SHADER_PARAMETER(int, ThreadCount)
SHADER_PARAMETER(int, GroupCount)
SHADER_PARAMETER(uint32, HitLightingForceOpaque)
SHADER_PARAMETER(uint32, HitLightingShadowMode)
SHADER_PARAMETER(uint32, HitLightingShadowTranslucencyMode)
SHADER_PARAMETER(uint32, HitLightingDirectLighting)
SHADER_PARAMETER(uint32, HitLightingSkylight)
SHADER_PARAMETER(uint32, UseReflectionCaptures)
SHADER_PARAMETER(int, MaxRayAllocationCount)
SHADER_PARAMETER(float, MaxTraceDistance)
SHADER_PARAMETER(float, FarFieldMaxTraceDistance)
SHADER_PARAMETER(float, NearFieldMaxTraceDistanceDitherScale)
SHADER_PARAMETER(float, NearFieldSceneRadius)
SHADER_PARAMETER(uint32, ApplySkylightStage)
SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FVirtualVoxelParameters, HairStrandsVoxel)
// Output
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float3>, RWRadiance)
SHADER_PARAMETER_RDG_BUFFER_UAV(RWStructuredBuffer<LumenVisualize::FTraceDataPacked>, RWTraceDataPacked)
END_SHADER_PARAMETER_STRUCT()
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, Lumen::ERayTracingShaderDispatchType ShaderDispatchType, FShaderCompilerEnvironment& OutEnvironment)
{
FLumenHardwareRayTracingShaderBase::ModifyCompilationEnvironment(Parameters, ShaderDispatchType, Lumen::ESurfaceCacheSampling::HighResPages, OutEnvironment);
OutEnvironment.SetDefine(TEXT("ENABLE_VISUALIZE_MODE"), 1);
OutEnvironment.SetDefine(TEXT("RECURSIVE_REFLECTION_TRACES"), 1);
}
static FPermutationDomain RemapPermutation(FPermutationDomain PermutationVector)
{
if (PermutationVector.Get<FHitLightingDim>())
{
PermutationVector.Set<FLumenVisualizeHardwareRayTracing::FSurfaceCacheAlphaMasking>(false);
}
else
{
PermutationVector.Set<FLumenVisualizeHardwareRayTracing::FRecursiveRefractionTraces>(false);
}
return PermutationVector;
}
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters, Lumen::ERayTracingShaderDispatchType ShaderDispatchType)
{
FPermutationDomain PermutationVector(Parameters.PermutationId);
if (RemapPermutation(PermutationVector) != PermutationVector)
{
return false;
}
if (PermutationVector.Get<FHitLightingDim>() && ShaderDispatchType == Lumen::ERayTracingShaderDispatchType::Inline)
{
return false;
}
return DoesPlatformSupportLumenGI(Parameters.Platform)
&& FLumenHardwareRayTracingShaderBase::ShouldCompilePermutation(Parameters, ShaderDispatchType);
}
static ERayTracingPayloadType GetRayTracingPayloadType(const int32 PermutationId)
{
FPermutationDomain PermutationVector(PermutationId);
if (PermutationVector.Get<FHitLightingDim>())
{
return ERayTracingPayloadType::RayTracingMaterial;
}
else
{
return ERayTracingPayloadType::LumenMinimal;
}
}
};
IMPLEMENT_LUMEN_RAYGEN_AND_COMPUTE_RAYTRACING_SHADERS(FLumenVisualizeHardwareRayTracing)
IMPLEMENT_GLOBAL_SHADER(FLumenVisualizeHardwareRayTracingRGS, "/Engine/Private/Lumen/LumenVisualizeHardwareRayTracing.usf", "LumenVisualizeHardwareRayTracingRGS", SF_RayGen);
IMPLEMENT_GLOBAL_SHADER(FLumenVisualizeHardwareRayTracingCS, "/Engine/Private/Lumen/LumenVisualizeHardwareRayTracing.usf", "LumenVisualizeHardwareRayTracingCS", SF_Compute);
void FDeferredShadingSceneRenderer::PrepareLumenHardwareRayTracingVisualize(const FViewInfo& View, TArray<FRHIRayTracingShader*>& OutRayGenShaders)
{
const EDiffuseIndirectMethod DiffuseIndirectMethod = GetViewPipelineState(View).DiffuseIndirectMethod;
if (Lumen::ShouldVisualizeHardwareRayTracing(*View.Family)
&& (LumenVisualize::UseHitLighting(View, DiffuseIndirectMethod) || LumenVisualize::UseFarField(*View.Family) || LumenReflections::UseHitLighting(View, DiffuseIndirectMethod) || LumenReflections::UseFarField(*View.Family)))
{
for (int32 HairOcclusion = 0; HairOcclusion < 2; HairOcclusion++)
{
for (int32 RayTracingTranslucent = 0; RayTracingTranslucent < 2; RayTracingTranslucent++)
{
FLumenVisualizeHardwareRayTracingRGS::FPermutationDomain PermutationVector;
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FHitLightingDim>(true);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FHairStrandsOcclusionDim>(HairOcclusion == 0);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FFarFieldDim>(false);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FRecursiveRefractionTraces>(RayTracingTranslucent > 0);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FSurfaceCacheAlphaMasking>(LumenHardwareRayTracing::UseSurfaceCacheAlphaMasking());
PermutationVector = FLumenVisualizeHardwareRayTracingRGS::RemapPermutation(PermutationVector);
TShaderRef<FLumenVisualizeHardwareRayTracingRGS> RayGenerationShader = View.ShaderMap->GetShader<FLumenVisualizeHardwareRayTracingRGS>(PermutationVector);
OutRayGenShaders.Add(RayGenerationShader.GetRayTracingShader());
}
}
}
}
void FDeferredShadingSceneRenderer::PrepareLumenHardwareRayTracingVisualizeLumenMaterial(const FViewInfo& View, TArray<FRHIRayTracingShader*>& OutRayGenShaders)
{
if (Lumen::ShouldVisualizeHardwareRayTracing(*View.Family) && !Lumen::UseHardwareInlineRayTracing(*View.Family))
{
for (int32 FarField = 0; FarField < 2; FarField++)
{
for (int32 HairOcclusion = 0; HairOcclusion < 2; HairOcclusion++)
{
for (int32 RayTracingTranslucent = 0; RayTracingTranslucent < 2; RayTracingTranslucent++)
{
FLumenVisualizeHardwareRayTracingRGS::FPermutationDomain PermutationVector;
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FHitLightingDim>(false);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FHairStrandsOcclusionDim>(HairOcclusion == 0);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FFarFieldDim>(FarField == 0);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FRecursiveRefractionTraces>(RayTracingTranslucent > 0);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FSurfaceCacheAlphaMasking>(LumenHardwareRayTracing::UseSurfaceCacheAlphaMasking());
PermutationVector = FLumenVisualizeHardwareRayTracingRGS::RemapPermutation(PermutationVector);
TShaderRef<FLumenVisualizeHardwareRayTracingRGS> RayGenerationShader = View.ShaderMap->GetShader<FLumenVisualizeHardwareRayTracingRGS>(PermutationVector);
OutRayGenShaders.Add(RayGenerationShader.GetRayTracingShader());
}
}
}
}
}
#endif // RHI_RAYTRACING
extern int32 GLumenReflectionHairStrands_VoxelTrace;
void LumenVisualize::VisualizeHardwareRayTracing(
FRDGBuilder& GraphBuilder,
const FScene* Scene,
const FSceneTextureParameters& SceneTextures,
const FViewInfo& View,
const FLumenSceneFrameTemporaries& FrameTemporaries,
const FLumenCardTracingParameters& TracingParameters,
FLumenIndirectTracingParameters& IndirectTracingParameters,
LumenVisualize::FSceneParameters& VisualizeParameters,
FRDGTextureRef SceneColor,
bool bVisualizeModeWithHitLighting,
EDiffuseIndirectMethod DiffuseIndirectMethod)
#if RHI_RAYTRACING
{
bool bTraceFarField = LumenVisualize::UseFarField(*View.Family);
bool bRetraceForHitLighting = LumenVisualize::UseHitLighting(View, DiffuseIndirectMethod) && bVisualizeModeWithHitLighting;
bool bForceHitLighting = LumenVisualize::IsHitLightingForceEnabled(View, DiffuseIndirectMethod);
bool bInlineRayTracing = Lumen::UseHardwareInlineRayTracing(*View.Family);
const bool bNeedTraceHairVoxel = HairStrands::HasViewHairStrandsVoxelData(View) && GLumenReflectionHairStrands_VoxelTrace > 0;
const bool bTraceTranslucent = LumenReflections::UseTranslucentRayTracing(View);
// Reflection scene view uses reflection setup
if (VisualizeParameters.VisualizeMode == VISUALIZE_MODE_REFLECTION_VIEW)
{
bTraceFarField = LumenReflections::UseFarField(*View.Family);
bRetraceForHitLighting = LumenReflections::UseHitLighting(View, DiffuseIndirectMethod);
bForceHitLighting = LumenReflections::IsHitLightingForceEnabled(View, DiffuseIndirectMethod);
}
// Disable modes that use hit-lighting when it's not available
if (!LumenHardwareRayTracing::IsRayGenSupported())
{
bRetraceForHitLighting = false;
bForceHitLighting = false;
}
// Cache near-field and far-field trace distances
const float FarFieldMaxTraceDistance = Lumen::GetFarFieldMaxTraceDistance();
const float MaxTraceDistance = IndirectTracingParameters.MaxTraceDistance;
// Generate tiles
FRDGBufferRef TileAllocatorBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), 1), TEXT("Lumen.Visualize.TileAllocator"));
FIntPoint TileCount = FMath::DivideAndRoundUp(VisualizeParameters.OutputViewSize, FIntPoint(FLumenVisualizeCreateRaysCS::GetThreadGroupSize2D()));
uint32 MaxTileCount = TileCount.X * TileCount.Y;
FRDGBufferRef TileDataPackedStructuredBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(sizeof(LumenVisualize::FTileDataPacked), MaxTileCount), TEXT("Lumen.Visualize.TileDataPacked"));
AddClearUAVPass(GraphBuilder, GraphBuilder.CreateUAV(TileAllocatorBuffer, PF_R32_UINT), 0);
{
FLumenVisualizeCreateTilesCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FLumenVisualizeCreateTilesCS::FParameters>();
{
// Input
PassParameters->View = View.ViewUniformBuffer;
PassParameters->VisualizeParameters = VisualizeParameters;
// Output
PassParameters->RWTileAllocator = GraphBuilder.CreateUAV(TileAllocatorBuffer, PF_R32_UINT);
PassParameters->RWTileDataPacked = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(TileDataPackedStructuredBuffer));
}
TShaderRef<FLumenVisualizeCreateTilesCS> ComputeShader = View.ShaderMap->GetShader<FLumenVisualizeCreateTilesCS>();
const FIntVector GroupSize(TileCount.X, TileCount.Y, 1);
FComputeShaderUtils::AddPass(
GraphBuilder,
RDG_EVENT_NAME("FLumenVisualizeCreateTilesCS"),
ComputeShader,
PassParameters,
GroupSize);
}
// Generate rays
// NOTE: GroupCount for emulated indirect-dispatch of raygen shaders dictates the maximum allocation size if GroupCount > MaxTileCount
uint32 RayGenThreadCount = CVarLumenVisualizeHardwareRayTracingThreadCount.GetValueOnRenderThread();
uint32 RayGenGroupCount = CVarLumenVisualizeHardwareRayTracingGroupCount.GetValueOnRenderThread();
uint32 RayCount = FMath::Max(MaxTileCount, RayGenGroupCount) * FLumenVisualizeCreateRaysCS::GetThreadGroupSize1D();
// Create rays within tiles
FRDGBufferRef RayAllocatorBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), 1), TEXT("Lumen.Visualize.RayAllocator"));
AddClearUAVPass(GraphBuilder, GraphBuilder.CreateUAV(RayAllocatorBuffer, PF_R32_UINT), 0);
FRDGBufferRef RayDataPackedBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(sizeof(LumenVisualize::FRayDataPacked), RayCount), TEXT("Lumen.Visualize.RayDataPacked"));
{
FLumenVisualizeCreateRaysCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FLumenVisualizeCreateRaysCS::FParameters>();
{
// Input
PassParameters->View = View.ViewUniformBuffer;
PassParameters->SceneTextures = SceneTextures;
PassParameters->VisualizeParameters = VisualizeParameters;
PassParameters->TileAllocator = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(TileAllocatorBuffer, PF_R32_UINT));
PassParameters->TileDataPacked = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(TileDataPackedStructuredBuffer));
PassParameters->MaxTraceDistance = MaxTraceDistance;
// Output
PassParameters->RWRayAllocator = GraphBuilder.CreateUAV(RayAllocatorBuffer, PF_R32_UINT);
PassParameters->RWRayDataPacked = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(RayDataPackedBuffer));
}
TShaderRef<FLumenVisualizeCreateRaysCS> ComputeShader = View.ShaderMap->GetShader<FLumenVisualizeCreateRaysCS>();
const FIntVector GroupSize(VisualizeCreateRaysDispatchSizeX, FMath::DivideAndRoundUp<int32>(RayCount, FLumenVisualizeCreateRaysCS::GetThreadGroupSize1D() * VisualizeCreateRaysDispatchSizeX), 1);
FComputeShaderUtils::AddPass(
GraphBuilder,
RDG_EVENT_NAME("FLumenVisualizeCreateRaysCS"),
ComputeShader,
PassParameters,
GroupSize);
}
// Dispatch rays, resolving some of the screen with surface cache entries and collecting secondary rays for hit-lighting
FRDGBufferRef TraceDataPackedBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(sizeof(LumenVisualize::FTraceDataPacked), RayCount), TEXT("Lumen.Visualize.TraceDataPacked"));
{
FLumenVisualizeHardwareRayTracingRGS::FParameters* PassParameters = GraphBuilder.AllocParameters<FLumenVisualizeHardwareRayTracingRGS::FParameters>();
{
SetLumenHardwareRayTracingSharedParameters(
GraphBuilder,
SceneTextures,
View,
TracingParameters,
&PassParameters->SharedParameters);
// Input
PassParameters->VisualizeParameters = VisualizeParameters;
PassParameters->RayAllocator = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(RayAllocatorBuffer, PF_R32_UINT));
PassParameters->RayDataPacked = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(RayDataPackedBuffer));
PassParameters->ThreadCount = RayGenThreadCount;
PassParameters->GroupCount = RayGenGroupCount;
PassParameters->MaxRayAllocationCount = RayCount;
PassParameters->MaxTraceDistance = MaxTraceDistance;
PassParameters->FarFieldMaxTraceDistance = FarFieldMaxTraceDistance;
PassParameters->NearFieldMaxTraceDistanceDitherScale = Lumen::GetNearFieldMaxTraceDistanceDitherScale(bTraceFarField);
PassParameters->NearFieldSceneRadius = Lumen::GetNearFieldSceneRadius(View, bTraceFarField);
PassParameters->ApplySkylightStage = 1;
if (bNeedTraceHairVoxel)
{
PassParameters->HairStrandsVoxel = HairStrands::BindHairStrandsVoxelUniformParameters(View);
}
// Output
PassParameters->RWRadiance = GraphBuilder.CreateUAV(SceneColor);
PassParameters->RWTraceDataPacked = GraphBuilder.CreateUAV(TraceDataPackedBuffer);
}
FLumenVisualizeHardwareRayTracingRGS::FPermutationDomain PermutationVector;
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FHitLightingDim>(false);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FFarFieldDim>(bTraceFarField);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FHairStrandsOcclusionDim>(bNeedTraceHairVoxel);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FRecursiveRefractionTraces>(bTraceTranslucent);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FSurfaceCacheAlphaMasking>(LumenHardwareRayTracing::UseSurfaceCacheAlphaMasking());
PermutationVector = FLumenVisualizeHardwareRayTracingRGS::RemapPermutation(PermutationVector);
FIntPoint DispatchResolution = FIntPoint(RayGenThreadCount, RayGenGroupCount);
if (bInlineRayTracing)
{
const FIntVector GroupCount = FComputeShaderUtils::GetGroupCount(DispatchResolution, FLumenVisualizeHardwareRayTracingCS::GetThreadGroupSize(View.GetShaderPlatform()));
FLumenVisualizeHardwareRayTracingCS::AddLumenRayTracingDispatch(
GraphBuilder,
RDG_EVENT_NAME("VisualizeHardwareRayTracing (inline) %ux%u", DispatchResolution.X, DispatchResolution.Y),
View,
PermutationVector,
PassParameters,
GroupCount,
ERDGPassFlags::Compute);
}
else
{
FLumenVisualizeHardwareRayTracingRGS::AddLumenRayTracingDispatch(
GraphBuilder,
RDG_EVENT_NAME("VisualizeHardwareRayTracing (raygen) %ux%u", DispatchResolution.X, DispatchResolution.Y),
View,
PermutationVector,
PassParameters,
DispatchResolution,
true,
ERDGPassFlags::Compute);
}
}
FRDGBufferRef CompactRaysIndirectArgsBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateIndirectDesc<FRHIDispatchIndirectParameters>(1), TEXT("Lumen.Visualize.CompactTracingIndirectArgs"));
{
FLumenVisualizeCompactRaysIndirectArgsCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FLumenVisualizeCompactRaysIndirectArgsCS::FParameters>();
{
PassParameters->RayAllocator = GraphBuilder.CreateSRV(RayAllocatorBuffer, PF_R32_UINT);
PassParameters->RWCompactRaysIndirectArgs = GraphBuilder.CreateUAV(CompactRaysIndirectArgsBuffer, PF_R32_UINT);
}
TShaderRef<FLumenVisualizeCompactRaysIndirectArgsCS> ComputeShader = View.ShaderMap->GetShader<FLumenVisualizeCompactRaysIndirectArgsCS>();
FComputeShaderUtils::AddPass(
GraphBuilder,
RDG_EVENT_NAME("FLumenVisualizeCompactRaysIndirectArgsCS"),
ComputeShader,
PassParameters,
FIntVector(1, 1, 1));
}
// Fire secondary rays for hit-lighting, resolving some of the screen and collecting miss rays
if (bRetraceForHitLighting)
{
// Compact rays which need to be re-traced
if ((CVarLumenVisualizeHardwareRayTracingCompact.GetValueOnRenderThread() != 0) || bForceHitLighting)
{
FRDGBufferRef CompactedRayAllocatorBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), 1), TEXT("Lumen.Visualize.CompactedRayAllocator"));
AddClearUAVPass(GraphBuilder, GraphBuilder.CreateUAV(CompactedRayAllocatorBuffer, PF_R32_UINT), 0);
FRDGBufferRef CompactedRayDataPackedBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(sizeof(LumenVisualize::FRayDataPacked), RayCount), TEXT("Lumen.Visualize.CompactedRayDataPacked"));
FRDGBufferRef CompactedTraceDataPackedBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(sizeof(LumenVisualize::FTraceDataPacked), RayCount), TEXT("Lumen.Visualize.CompactedTraceDataPacked"));
{
FLumenVisualizeCompactRaysCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FLumenVisualizeCompactRaysCS::FParameters>();
{
// Input
PassParameters->RayAllocator = GraphBuilder.CreateSRV(RayAllocatorBuffer, PF_R32_UINT);
PassParameters->RayDataPacked = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(RayDataPackedBuffer));
PassParameters->TraceDataPacked = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(TraceDataPackedBuffer));
PassParameters->MaxRayAllocationCount = RayCount;
// Output
PassParameters->RWCompactedRayAllocator = GraphBuilder.CreateUAV(CompactedRayAllocatorBuffer, PF_R32_UINT);
PassParameters->RWCompactedRayDataPacked = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(CompactedRayDataPackedBuffer));
PassParameters->RWCompactedTraceDataPacked = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(CompactedTraceDataPackedBuffer));
// Indirect args
PassParameters->CompactRaysIndirectArgs = CompactRaysIndirectArgsBuffer;
}
FLumenVisualizeCompactRaysCS::FPermutationDomain PermutationVector;
PermutationVector.Set<FLumenVisualizeCompactRaysCS::FCompactModeDim>(bForceHitLighting ? LumenVisualize::ECompactMode::ForceHitLighting : LumenVisualize::ECompactMode::HitLightingRetrace);
TShaderRef<FLumenVisualizeCompactRaysCS> ComputeShader = View.ShaderMap->GetShader<FLumenVisualizeCompactRaysCS>(PermutationVector);
FComputeShaderUtils::AddPass(
GraphBuilder,
RDG_EVENT_NAME("FLumenVisualizeCompactRaysCS"),
ComputeShader,
PassParameters,
PassParameters->CompactRaysIndirectArgs,
0);
}
RayAllocatorBuffer = CompactedRayAllocatorBuffer;
RayDataPackedBuffer = CompactedRayDataPackedBuffer;
TraceDataPackedBuffer = CompactedTraceDataPackedBuffer;
}
// Bucket rays which hit objects, but do not have a surface-cache id by their material id
if (CVarLumenVisualizeHardwareRayTracingBucketMaterials.GetValueOnRenderThread())
{
FRDGBufferRef BucketRaysByMaterialIdIndirectArgsBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateIndirectDesc<FRHIDispatchIndirectParameters>(1), TEXT("Lumen.Visualize.BucketRaysByMaterialIdIndirectArgsBuffer"));
{
FLumenVisualizeBucketRaysByMaterialIdIndirectArgsCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FLumenVisualizeBucketRaysByMaterialIdIndirectArgsCS::FParameters>();
{
PassParameters->RayAllocator = GraphBuilder.CreateSRV(RayAllocatorBuffer, PF_R32_UINT);
PassParameters->RWBucketRaysByMaterialIdIndirectArgs = GraphBuilder.CreateUAV(BucketRaysByMaterialIdIndirectArgsBuffer, PF_R32_UINT);
}
TShaderRef<FLumenVisualizeBucketRaysByMaterialIdIndirectArgsCS> ComputeShader = View.ShaderMap->GetShader<FLumenVisualizeBucketRaysByMaterialIdIndirectArgsCS>();
FComputeShaderUtils::AddPass(
GraphBuilder,
RDG_EVENT_NAME("FLumenVisualizeBucketRaysByMaterialIdIndirectArgsCS"),
ComputeShader,
PassParameters,
FIntVector(1, 1, 1));
}
FRDGBufferRef BucketedRayDataPackedBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(sizeof(LumenVisualize::FRayDataPacked), RayCount), TEXT("Lumen.Visualize.BucketedRayDataPacked"));
FRDGBufferRef BucketedTraceDataPackedBuffer = GraphBuilder.CreateBuffer(FRDGBufferDesc::CreateStructuredDesc(sizeof(LumenVisualize::FTraceDataPacked), RayCount), TEXT("Lumen.Visualize.BucketedTraceDataPacked"));
{
FLumenVisualizeBucketRaysByMaterialIdCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FLumenVisualizeBucketRaysByMaterialIdCS::FParameters>();
{
// Input
PassParameters->RayAllocator = GraphBuilder.CreateSRV(RayAllocatorBuffer, PF_R32_UINT);
PassParameters->RayDataPacked = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(RayDataPackedBuffer));
PassParameters->TraceDataPacked = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(TraceDataPackedBuffer));
PassParameters->MaxRayAllocationCount = RayCount;
// Output
PassParameters->RWRayDataPacked = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(BucketedRayDataPackedBuffer));
PassParameters->RWTraceDataPacked = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(BucketedTraceDataPackedBuffer));
// Indirect args
PassParameters->BucketRaysByMaterialIdIndirectArgs = BucketRaysByMaterialIdIndirectArgsBuffer;
}
TShaderRef<FLumenVisualizeBucketRaysByMaterialIdCS> ComputeShader = View.ShaderMap->GetShader<FLumenVisualizeBucketRaysByMaterialIdCS>();
FComputeShaderUtils::AddPass(
GraphBuilder,
RDG_EVENT_NAME("FLumenVisualizeBucketRaysByMaterialIdCS"),
ComputeShader,
PassParameters,
PassParameters->BucketRaysByMaterialIdIndirectArgs,
0);
RayDataPackedBuffer = BucketedRayDataPackedBuffer;
TraceDataPackedBuffer = BucketedTraceDataPackedBuffer;
}
}
FLumenVisualizeHardwareRayTracingRGS::FParameters* PassParameters = GraphBuilder.AllocParameters<FLumenVisualizeHardwareRayTracingRGS::FParameters>();
{
SetLumenHardwareRayTracingSharedParameters(
GraphBuilder,
SceneTextures,
View,
TracingParameters,
&PassParameters->SharedParameters);
// Input
PassParameters->VisualizeParameters = VisualizeParameters;
PassParameters->RayAllocator = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(RayAllocatorBuffer, PF_R32_UINT));
PassParameters->RayDataPacked = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(RayDataPackedBuffer));
PassParameters->TraceDataPacked = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(TraceDataPackedBuffer));
PassParameters->ThreadCount = RayGenThreadCount;
PassParameters->GroupCount = RayGenGroupCount;
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->UseReflectionCaptures = LumenHardwareRayTracing::UseReflectionCapturesForHitLighting();
PassParameters->MaxRayAllocationCount = RayCount;
PassParameters->MaxTraceDistance = MaxTraceDistance;
PassParameters->FarFieldMaxTraceDistance = FarFieldMaxTraceDistance;
PassParameters->NearFieldMaxTraceDistanceDitherScale = Lumen::GetNearFieldMaxTraceDistanceDitherScale(bTraceFarField);
PassParameters->NearFieldSceneRadius = Lumen::GetNearFieldSceneRadius(View, bTraceFarField);
// Even though the retrace should only be processing hits, which don't need skylight, the retrace may miss as it uses a different FRayTracingPipelineState
PassParameters->ApplySkylightStage = 1;
if (bNeedTraceHairVoxel)
{
PassParameters->HairStrandsVoxel = HairStrands::BindHairStrandsVoxelUniformParameters(View);
}
// Output
PassParameters->RWRadiance = GraphBuilder.CreateUAV(SceneColor);
}
FLumenVisualizeHardwareRayTracingRGS::FPermutationDomain PermutationVector;
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FHitLightingDim>(true);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FFarFieldDim>(false);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FHairStrandsOcclusionDim>(bNeedTraceHairVoxel);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FRecursiveRefractionTraces>(bTraceTranslucent);
PermutationVector.Set<FLumenVisualizeHardwareRayTracingRGS::FSurfaceCacheAlphaMasking>(LumenHardwareRayTracing::UseSurfaceCacheAlphaMasking());
PermutationVector = FLumenVisualizeHardwareRayTracingRGS::RemapPermutation(PermutationVector);
TShaderRef<FLumenVisualizeHardwareRayTracingRGS> RayGenerationShader = View.ShaderMap->GetShader<FLumenVisualizeHardwareRayTracingRGS>(PermutationVector);
FIntPoint DispatchResolution = FIntPoint(RayGenThreadCount, RayGenGroupCount);
GraphBuilder.AddPass(
RDG_EVENT_NAME("VisualizeHardwareRayTracing[retrace for hit-lighting] %ux%u", DispatchResolution.X, DispatchResolution.Y),
PassParameters,
ERDGPassFlags::Compute,
[PassParameters, &View, RayGenerationShader, DispatchResolution](FRDGAsyncTask, FRHICommandList& RHICmdList)
{
FRHIBatchedShaderParameters& GlobalResources = RHICmdList.GetScratchShaderParameters();
SetShaderParameters(GlobalResources, RayGenerationShader, *PassParameters);
FRHIUniformBuffer* SceneUniformBuffer = PassParameters->SharedParameters.TracingParameters.Scene->GetRHI();
FRHIUniformBuffer* NaniteRayTracingUniformBuffer = PassParameters->SharedParameters.NaniteRayTracing->GetRHI();
TOptional<FScopedUniformBufferStaticBindings> StaticUniformBufferScope = RayTracing::BindStaticUniformBufferBindings(View, SceneUniformBuffer, NaniteRayTracingUniformBuffer, RHICmdList);
FRayTracingPipelineState* Pipeline = View.MaterialRayTracingData.PipelineState;
FRHIShaderBindingTable* SBT = View.MaterialRayTracingData.ShaderBindingTable;
RHICmdList.RayTraceDispatch(Pipeline, RayGenerationShader.GetRayTracingShader(), SBT, GlobalResources, DispatchResolution.X, DispatchResolution.Y);
}
);
}
}
#else
{
unimplemented();
}
#endif