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