Hi @TJ.Ashby-ARA,
Thank you for your reply, my solution is not yet on Github, but this is what I have done and it ākind offā works. However, it often crashes due to memory access violation, most likely as a result of not properly protecting the output buffer (however, Iām very new to this and have no clue how to lock it).
This is what Iāve done:
void FRayGenTest::Execute_RenderThread(FPostOpaqueRenderParameters &Parameters)
{
if (!mCachedParams.Scene->IsCreated()) return;
FRDGBuilder *GraphBuilder = Parameters.GraphBuilder;
FRHICommandListImmediate &RHICmdList = GraphBuilder->RHICmdList;
if (!(bCachedParamsAreValid && mCachedParams.RenderTarget))
{
return;
}
// Render Thread Assertion
check(IsInRenderingThread());
TShaderMapRef<FRayGenTestRGS> RayGenTestRGS(GetGlobalShaderMap(GMaxRHIFeatureLevel));
bool bIsShaderValid = RayGenTestRGS.IsValid();
if (!bIsShaderValid)
return;
const FIntPoint TextureSize = {mCachedParams.RenderTarget->SizeX, mCachedParams.RenderTarget->SizeY};
FRHITextureCreateDesc TextureDesc = FRHITextureCreateDesc::Create2D(TEXT("RaytracingTestOutput"), TextureSize.X, TextureSize.Y, mCachedParams.RenderTarget->GetFormat());
TextureDesc.AddFlags(TexCreate_ShaderResource | TexCreate_UAV | TexCreate_RenderTargetable);
mShaderOutputTexture = RHICreateTexture(TextureDesc);
// set shader parameters
FRayGenTestRGS::FParameters *PassParameters = GraphBuilder->AllocParameters<FRayGenTestRGS::FParameters>();
PassParameters->ViewUniformBuffer = Parameters.View->ViewUniformBuffer;
PassParameters->outTex = RHICmdList.CreateUnorderedAccessView(mShaderOutputTexture);
FTexture2DRHIRef OriginalRT = mCachedParams.RenderTarget->GetRenderTargetResource()->GetTexture2DRHI();
FRDGTexture *CopyToRDGTexture = GraphBuilder->RegisterExternalTexture(CreateRenderTarget(OriginalRT, TEXT("RaytracingTestCopyToRT")));
FRDGTexture *OutputRDGTexture = GraphBuilder->RegisterExternalTexture(CreateRenderTarget(mShaderOutputTexture, TEXT("RaytracingTestOutputRT")));
FRHIRayTracingScene *RHIScene = mCachedParams.Scene->GetRHIRayTracingScene();
FRDGBufferSRVRef layerView = mCachedParams.Scene->GetLayerView(ERayTracingSceneLayer::Base);
GraphBuilder->AddPass(
RDG_EVENT_NAME("RayGenTest"),
PassParameters,
ERDGPassFlags::Compute,
[PassParameters, RayGenTestRGS, TextureSize, RHIScene, layerView, CopyToRDGTexture, OutputRDGTexture](FRHIRayTracingCommandList &RHICmdList)
{
PassParameters->TLAS = layerView->GetRHI();
FRayTracingShaderBindingsWriter GlobalResources;
SetShaderParameters(GlobalResources, RayGenTestRGS, *PassParameters);
FRayTracingPipelineStateInitializer PSOInitializer;
PSOInitializer.MaxPayloadSizeInBytes = GetRayTracingPayloadTypeMaxSize(FRayGenTestRGS::GetRayTracingPayloadType(0));
PSOInitializer.bAllowHitGroupIndexing = false;
// Set RayGen shader
TArray<FRHIRayTracingShader *> RayGenShaderTable;
RayGenShaderTable.Add(GetGlobalShaderMap(GMaxRHIFeatureLevel)->GetShader<FRayGenTestRGS>().GetRayTracingShader());
PSOInitializer.SetRayGenShaderTable(RayGenShaderTable);
// Set ClosestHit shader
TArray<FRHIRayTracingShader *> RayHitShaderTable;
RayHitShaderTable.Add(GetGlobalShaderMap(GMaxRHIFeatureLevel)->GetShader<FRayGenTestCHS>().GetRayTracingShader());
PSOInitializer.SetHitGroupTable(RayHitShaderTable);
// Set Miss shader
TArray<FRHIRayTracingShader *> RayMissShaderTable;
RayMissShaderTable.Add(GetGlobalShaderMap(GMaxRHIFeatureLevel)->GetShader<FRayGenTestMS>().GetRayTracingShader());
PSOInitializer.SetMissShaderTable(RayMissShaderTable);
// dispatch ray trace shader
FRayTracingPipelineState *PipeLine = PipelineStateCache::GetAndOrCreateRayTracingPipelineState(RHICmdList, PSOInitializer);
RHICmdList.SetRayTracingMissShader(RHIScene, 0, PipeLine, 0 /* ShaderIndexInPipeline */, 0, nullptr, 0);
RHICmdList.RayTraceDispatch(PipeLine, RayGenTestRGS.GetRayTracingShader(), RHIScene, GlobalResources, TextureSize.X, TextureSize.Y);
FRHICopyTextureInfo CopyInfo;
CopyInfo.Size = FIntVector(TextureSize.X, TextureSize.Y, 0);
RHICmdList.CopyTexture(OutputRDGTexture->GetRHI(), CopyToRDGTexture->GetRHI(), CopyInfo);
});
}
Ultimately, though, what I am looking for is more of a replacement for the CPU based LineTrace function, because I need to cast a lot of rays (for LIDAR simulation). So I would like to in the future rewrite it a bit to use a structured buffer with the desired ray properties and input and a vector with the hit results as output.
I also found the RayTracing test case in the Unreal Engine source code, but I was not able to adapt this to my needs, because I struggled to get access to the TLAS structure.
Please let me know if you have any suggestions on how to solve the crashing issues when copying the texture buffer. Thank you for your support!