@ZkarmaKun ok so I got it up and running, but I get a crash deep inside the d12 API.
This my shader:
#include "/Engine/Public/Platform.ush"
#include "/Engine/Private/Common.ush"
#include "/Engine/Private/RayTracing/RayTracingCommon.ush"
#include "/Engine/Private/RayTracing/RayTracingHitGroupCommon.ush"
RWTexture2D<float4> outTex;
float3 wsCamPos;
float3 wsCamU, wsCamV, wsCamW; // camera up, right, and forward vectors
RaytracingAccelerationStructure TLAS;
struct Payload
{
float3 color;
};
[shader("raygeneration")]
void RayTraceTestRGS()
{
uint2 curPixel = DispatchRaysIndex().xy;
uint2 totalPixels = DispatchRaysDimensions().xy;
float2 pixelCenter = (curPixel + float2(0.5, 0.5)) / totalPixels;
float2 ndc = float2(2, -2) * pixelCenter + float2(-1, 1); // Normalized device coords
float3 pixelRayDir = ndc.x * wsCamU + ndc.y * wsCamV + wsCamW;
RayDesc ray;
ray.Origin = wsCamPos;
ray.Direction = normalize(pixelRayDir);
ray.TMin = 0.0f;
ray.TMax = 1e+38f;
Payload payload = (Payload) 0;
TraceRay(TLAS,
0,
0xFF,
0,
2,
0,
ray,
payload);
//outTex[curPixel] = payload.IsHit() ? float4(1, 1, 1, 1) : float4(0, 0, 0, 1);
outTex[curPixel] = float4(payload.color, 1);
}
[shader("miss")]
void RayTraceTestMS(inout Payload data)
{
//data.SetMiss();
data.color = 0;
}
[shader("closesthit")]
void RayTraceTestCHS(inout Payload data, BuiltInTriangleIntersectionAttributes attribs)
{
//data.HitT = 1.0f;
data.color = 0;
}
This is my renderer callback
void RayGenTest::Execute_RenderThread(FRDGBuilder& builder, const FSceneTextures& SceneTextures)
#if RHI_RAYTRACING
{
FRHICommandListImmediate& RHICmdList = builder.RHICmdList;
//If there's no cached parameters to use, skip
//If no Render Target is supplied in the cachedParams, skip
if (!(bCachedParamsAreValid && cachedParams.RenderTarget))
{
return;
}
//Render Thread Assertion
check(IsInRenderingThread());
//If the render target is not valid, get an element from the render target pool by supplying a Descriptor
if (!ShaderOutput.IsValid())
{
//UE_LOG(LogTemp, Warning, TEXT("Compute Shader Output Not Valid; re-generating"));
FIntPoint Size = cachedParams.GetRenderTargetSize();
FPooledRenderTargetDesc ComputeShaderOutputDesc(FPooledRenderTargetDesc::Create2DDesc(cachedParams.GetRenderTargetSize(), cachedParams.RenderTarget->GetRenderTargetResource()->TextureRHI->GetFormat(), FClearValueBinding::None, TexCreate_None, TexCreate_ShaderResource | TexCreate_UAV, false));
ComputeShaderOutputDesc.DebugName = TEXT("ForceFieldCS_Output_RenderTarget1");
GRenderTargetPool.FindFreeElement(RHICmdList, ComputeShaderOutputDesc, ShaderOutput, TEXT("ForceFieldCS_Output_RenderTarget2"));
}
FRHIRayTracingScene* RHIScene = cachedParams.Scene->GetRHIRayTracingScene();
FRayGenTestRGS::FParameters *PassParameters = builder.AllocParameters<FRayGenTestRGS::FParameters>();
PRAGMA_DISABLE_DEPRECATION_WARNINGS // Missing API for UAV prevents me from using the UAV.
PassParameters->outTex = ShaderOutput->GetRenderTargetItem().UAV;
PRAGMA_ENABLE_DEPRECATION_WARNINGS
PassParameters->wsCamPos = static_cast<FVector3f>(cachedParams.CameraTransform.GetTranslation());
PassParameters->wsCamU = static_cast<FVector3f>(cachedParams.CameraTransform.GetRotation().GetUpVector());
PassParameters->wsCamV = static_cast<FVector3f>(cachedParams.CameraTransform.GetRotation().GetRightVector());
PassParameters->wsCamW = static_cast<FVector3f>(cachedParams.CameraTransform.GetRotation().GetForwardVector());
PassParameters->TLAS = cachedParams.Scene->GetLayerSRVChecked(ERayTracingSceneLayer::Base);
TShaderMapRef<FRayGenTestRGS> RayGenTestRGS(GetGlobalShaderMap(GMaxRHIFeatureLevel));
FIntPoint TextureSize = {cachedParams.RenderTarget->SizeX, cachedParams.RenderTarget->SizeY};
builder.AddPass(
RDG_EVENT_NAME("RayGenTest"),
PassParameters,
ERDGPassFlags::Compute,
[PassParameters, RayGenTestRGS, TextureSize, RHIScene](FRHIRayTracingCommandList& RHICmdList)
{
FRayTracingShaderBindingsWriter GlobalResources;
SetShaderParameters(GlobalResources, RayGenTestRGS, *PassParameters);
FRayTracingPipelineStateInitializer PSOInitializer;
PSOInitializer.MaxPayloadSizeInBytes = RAY_TRACING_MAX_ALLOWED_PAYLOAD_SIZE;
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);
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);
}
);
//Copy shader's output to the render target provided by the client
RHICmdList.CopyTexture(ShaderOutput->GetRenderTargetItem().ShaderResourceTexture, cachedParams.RenderTarget->GetRenderTargetResource()->TextureRHI, FRHICopyTextureInfo());
//Unbind the previously bound render targets
GRenderTargetPool.FreeUnusedResource(ShaderOutput);
}
#else // !RHI_RAYTRACING
{
unimplemented();
}
#endif
output error:
D3D12 ERROR: ID3D12Device::CreateStateObject: Resource bindings for function "RayGen_325ba7afe8c02761" not compatible with associated root signatures (if any): local root signature object: 0x000001759C355090:'Unnamed ID3D12RootSignature Object', global root signature object: 0x00000175AEF8F9A0:'Unnamed ID3D12RootSignature Object'. Error detail: Shader CBV descriptor range (BaseShaderRegister=0, NumDescriptors=1, RegisterSpace=0) is not fully bound in a root signature. If the intent is this will be resolved later when this state object is combined with other state object(s), use a D3D12_STATE_OBJECT_CONFIG subobject with D3D12_STATE_OBJECT_FLAG_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITIONS set in Flags. [ STATE_CREATION ERROR #1194: CREATE_STATE_OBJECT_ERROR]
D3D12: **BREAK** enabled for the previous message, which was: [ ERROR STATE_CREATION #1194: CREATE_STATE_OBJECT_ERROR ]
Exception thrown at 0x00007FFB6A91CD29 (KernelBase.dll) in UnrealEditor.exe: 0x0000087A (parameters: 0x0000000000000001, 0x00000028DC7FBDE0, 0x00000028DC7FDBA0).
Notice I’ve manager to get the TLAS from the ray tracing scene. I’ve also called the TraceRay directly with my own payload struct, that is because I could not get the shader compiler to properly include the headers there, thus making fail to to recognize the FMinimalPayload struct.
I suspect that UE assign its own default callbacks for missing implementation (intersection and anyhit) causing a signature miss-match
I also failed to get the UE TraceRay warpper (TraceVisibilityRay) because that requires me to get FViewInfo on the cpp side, which also giving me a hard time (I was able to create one from the player camera, but that’s not good enough because the ViewUniformBuffer was uninitialized, and I don’t know how to do it)
I would really appreciate if you could share you code, I understand if you don’t wish to.