Advertisement

New to DXR: It Doesn't Render Geometry

Started by May 12, 2024 03:04 AM
6 comments, last by isu diss 6 months, 4 weeks ago

Hi, I just wrote my first ray tracer using DX12 DXR. Everything checks out, doesn't produce error when debugged yet it doesn't render my model on screen. Here are some screen shots. Q1: Is it a must to have an index buffer of the model when we create accel. struct.? only difference between my implementation and Microsoft's sample cube rendering. My resource loader doesn't create an index buffer only the vertex buffer. I pass the vertex buffer as a structured buffer.

	void VertexBufferView(ComPtr<ID3D12Device5> inDevice, ComPtr<ID3D12DescriptorHeap> mSrvHeap)const
	{
		D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
		srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
		srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
		srvDesc.Buffer.FirstElement = 0;
		srvDesc.Buffer.NumElements = mMeshGeometry.size();

		srvDesc.Format = DXGI_FORMAT_UNKNOWN;
		srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
		srvDesc.Buffer.StructureByteStride = VertexByteStride;

		CD3DX12_CPU_DESCRIPTOR_HANDLE srvDescriptorHandle(mSrvHeap->GetCPUDescriptorHandleForHeapStart());
		inDevice->CreateShaderResourceView(Mesh_Vertex_Buffer_GPU.Get(), &srvDesc, srvDescriptorHandle);
	}
	
	void CreateMeshVertexBuffer(ComPtr<ID3D12Device5> inDevice, ComPtr<ID3D12GraphicsCommandList5> inCommandList)
	{
		const UINT vbByteSize = (UINT)mMeshGeometry.size() * sizeof(RE_VERTEX);

		Mesh_Vertex_Buffer_GPU = Common::CreateDefaultBuffer(inDevice.Get(),
			inCommandList.Get(), mMeshGeometry.data(), vbByteSize, Mesh_Vertex_Buffer_Uploader);

		VertexByteStride = sizeof(RE_VERTEX);
		VertexBufferByteSize = vbByteSize;
	}
	...............................................
	
void RESrcLoader::BuildAccelerationStructures()
{
	D3D12_RAYTRACING_GEOMETRY_DESC geometryDesc = {};
	geometryDesc.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES;
	geometryDesc.Triangles.Transform3x4 = 0;
	geometryDesc.Triangles.VertexFormat = DXGI_FORMAT_R32G32B32_FLOAT;
	geometryDesc.Triangles.VertexCount = static_cast<UINT>(Model[4].mMeshGeometry.size());
	geometryDesc.Triangles.VertexBuffer.StartAddress = Model[4].Mesh_Vertex_Buffer_GPU->GetGPUVirtualAddress();
	geometryDesc.Triangles.VertexBuffer.StrideInBytes = sizeof(RE_VERTEX);
	geometryDesc.Triangles.IndexCount = 0;
	geometryDesc.Triangles.IndexFormat = DXGI_FORMAT_UNKNOWN;
	geometryDesc.Triangles.IndexBuffer = NULL;
	................................................

anyone pls

Advertisement

isu diss said:
Q1: Is it a must to have an index buffer of the model when we create accel. struct.?

I'm sure Microsoft hides the answer somewhere in their DXR API specs. But after a quick search i could not find anything.

But i assume it's a yes.
Index buffer is faster and needs less memory than triangles with all vertices duplicated 6 times, so why should they support inefficient data formats?

So you want to convert to index buffer anyway. Both RT and raster will be faster ans memory will be less. If you're lucky, it fixes the issue as well.

EDIT:

Thinking of it, indexing might be even slower for RT, since resolving the indirection could cause more cache misses.

JoeJ said:
I'm sure Microsoft hides the answer somewhere in their DXR API specs. But after a quick search i could not find anything.

It is not a must - the specs say somewhat directly D3D12_RAYTRACING_GEOMETRY_DESC with Type D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES does allow you to specify IndexFormat to DXGI_FORMAT_UNKNOWN in D3D12_RAYTRACING_GEOMETRY_TRIANGLES_DESC

When you specify that and along with it IndexBuffer to NULL - then you specify triangles as a list (not strip, just list). The problem is, whether that actually works - because DXR is still somewhat vendor dependent. And debug layer does not work properly all the time.

Example of such issue is setting TLAS in pipeline state for DispatchRays. AMD (RDNA2 and RDNA3) allow you to set it through descriptor table. NVidia (Ada Lovelace, but older also likely) does NOT - it requires TLAS to be passed as root SRV param - otherwise it freezes. Debug layer gives no message about it, just freezes. Note: Not sure if this is message worthy for DX12 discord or not.

And there is a LOT of such details that can completely break it. You won't figure out these details unless you start exactly from reference implementation and slowly replace that into yours.

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Thanks sirs, @joej @vilem otte you guys are the only ones to answer whenever there's a question. I still remember how you helped me to resolve the issue in lens flare effect long ago Vilem Otte. I figured out all the things you guys posted here. my structured buffer is ok, and DXR can work without index buffer. Thanks, back to the original issue.

Since I was sick with fever, I didn't have time to do this. This is what I did. As the debug doesn't output an issue, I identified the areas that could possibly be erroneous in my code. I added my code to the working sample of Microsoft and see there if it works. It worked. My code works on MS sample yet didn't work on my engine. I came to a conclusion that ray tracing is beyond my capabilities here and give up. Out of sudden, my mind told me to change this. In HLSL, matrices must be passed as transposed, this is what I did(g_sceneCB.mInvWVP). But I don't know why it worked on MS Sample without transposing.

void GenerateCameraRay(uint2 index, out float3 origin, out float3 direction)
{
    float2 xy = index + 0.5f; // center in the middle of the pixel.
    float2 screenPos = xy / DispatchRaysDimensions().xy * 2.0 - 1.0;

    // Invert Y for DirectX-style coordinates.
    screenPos.y = -screenPos.y;

    // Unproject the pixel coordinate into a ray.
    float4 world = mul(float4(screenPos, 0, 1), g_sceneCB.mInvWVP);

    world.xyz /= world.w;
    origin = g_sceneCB.CameraPos.xyz;
    direction = normalize(world.xyz - origin);
}

After all, my problem was with the matrix, once I fixed it voila! my model got rendered correctly. My GPU is AMD RX6700XT. Here's a snap of my model.

Hi, new question. I implemented my sky shader in the miss shader to render the environment. It gives me this result. Can anyone give me the answer? why it contains noises. In my raster counter part of the same engine, I implemented it in the compute shader, it gives me a nice result.

Advertisement

anyone pls

This topic is closed to new replies.

Advertisement