Ok, I think I figured out what is missing in the tutorial
As I thought, it totally misses the geometry binds to the hit shaders and to do that we need
- bind geometry from the current view to the shader
- set it to the hit shader group using RHICmdList.SetRayTracingHitGroups()
in Engine/Plugins/FX/Niagara/Source/NiagaraShader/Private/NiagaraAsyncGpuTraceProviderHwrt.cpp there is a nice piece of code for doing that
static void BindNiagaraRayTracingMeshCommands(...)
{
FConcurrentLinearBulkObjectAllocator Allocator;
FRayTracingLocalShaderBindings* Bindings = nullptr;
FRHIUniformBuffer** UniformBufferArray = nullptr;
if (RHICmdList.Bypass())
{
Bindings = reinterpret_cast<FRayTracingLocalShaderBindings*>(Allocator.Malloc(MergedBindingsSize, alignof(FRayTracingLocalShaderBindings)));
UniformBufferArray = reinterpret_cast<FRHIUniformBuffer**>(Allocator.Malloc(UniformBufferArraySize, alignof(FRHIUniformBuffer*)));
}
else
{
Bindings = reinterpret_cast<FRayTracingLocalShaderBindings*>(RHICmdList.Alloc(MergedBindingsSize, alignof(FRayTracingLocalShaderBindings)));
UniformBufferArray = reinterpret_cast<FRHIUniformBuffer**>(RHICmdList.Alloc(UniformBufferArraySize, alignof(FRHIUniformBuffer*)));
}
...
for (const FRayTracingShaderBindingData DirtyShaderBinding : DirtyShaderBindings)
{
const FRayTracingMeshCommand& MeshCommand = *DirtyShaderBinding.RayTracingMeshCommand;
FRayTracingLocalShaderBindings Binding = {};
Binding.RecordIndex = DirtyShaderBinding.SBTRecordIndex;
Binding.Geometry = DirtyShaderBinding.RayTracingGeometry;
Binding.SegmentIndex = MeshCommand.GeometrySegmentIndex;
Binding.UserData = PackUserData(MeshCommand);
Binding.UniformBuffers = UniformBufferArray;
Binding.NumUniformBuffers = NumUniformBuffers;
Bindings[BindingIndex] = Binding;
BindingIndex++;
}
RHICmdList.SetRayTracingHitGroups(
SBT,
Pipeline,
NumTotalBindings,
Bindings,
bCopyDataToInlineStorage);
RHICmdList.SetRayTracingMissShader(SBT, 0, Pipeline, 0 /* ShaderIndexInPipeline */, 0, nullptr, 0);
RHICmdList.CommitShaderBindingTable(SBT);
}
After implementing this part (just copy this function to RayGenTest class and call it after setting the pipeline), and all works as expected ![]()
This is my custom hw RT shader that set depth (aka normalized RayCurrentT value) as output color
After doing that, I guess you’re free to pick and use any payload you want
