简单地说:我试图在D3D12中绑定和使用深度缓冲区,但它不起作用。深度缓冲区被正确地创建和绑定(我可以在nsight图形中看到它),但是只需要0.0f或1.0f (清除值)。我最初认为这可能是我的投影矩阵的问题,所以我在附近和远的Z玩,但我没有得到任何改进。
以下代码用于创建深度缓冲区:
// === Create DSV descriptor heap
D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc;
ZeroMemory(&dsvHeapDesc, sizeof(D3D12_DESCRIPTOR_HEAP_DESC));
dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
dsvHeapDesc.NumDescriptors = 1;
dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
dsvHeapDesc.NodeMask = NULL;
ptrDevice->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_ptrDsvDescriptorHeap))
// === Create depth buffer resource
// Describe heap
D3D12_HEAP_PROPERTIES dsHeapProperties;
ZeroMemory(&dsHeapProperties, sizeof(&dsHeapProperties));
dsHeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
dsHeapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
dsHeapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
dsHeapProperties.CreationNodeMask = NULL;
dsHeapProperties.VisibleNodeMask = NULL;
// Describe resource
D3D12_RESOURCE_DESC dsResDesc;
ZeroMemory(&dsResDesc, sizeof(D3D12_RESOURCE_DESC));
dsResDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
dsResDesc.Alignment = 0;
dsResDesc.Width = width;
dsResDesc.Height = height;
dsResDesc.DepthOrArraySize = 1;
dsResDesc.MipLevels = 1;
dsResDesc.Format = DXGI_FORMAT_D32_FLOAT;
dsResDesc.SampleDesc.Count = 1;
dsResDesc.SampleDesc.Quality = 0;
dsResDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
dsResDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
// Describe clear value
D3D12_CLEAR_VALUE clearValueDs;
ZeroMemory(&clearValueDs, sizeof(D3D12_CLEAR_VALUE));
clearValueDs.Format = DXGI_FORMAT_D32_FLOAT;
clearValueDs.DepthStencil.Depth = 1.0f;
clearValueDs.DepthStencil.Stencil = 0;
ptrDevice->CreateCommittedResource(
&dsHeapProperties,
D3D12_HEAP_FLAG_NONE,
&dsResDesc,
D3D12_RESOURCE_STATE_DEPTH_WRITE,
&clearValueDs,
IID_PPV_ARGS(&m_ptrDepthStencil)
);
// === Create view description
D3D12_DEPTH_STENCIL_VIEW_DESC dsViewDesk;
ZeroMemory(&dsViewDesk, sizeof(D3D12_DEPTH_STENCIL_VIEW_DESC));
dsViewDesk.Format = DXGI_FORMAT_D32_FLOAT;
dsViewDesk.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
dsViewDesk.Flags = D3D12_DSV_FLAG_NONE;
dsViewDesk.Texture2D.MipSlice = 0;
D3D12_CPU_DESCRIPTOR_HANDLE heapHandleDsv = m_ptrDsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
ptrDevice->CreateDepthStencilView(m_ptrDepthStencil, &dsViewDesk, heapHandleDsv);
在frame方法中,执行以下代码
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = m_ptrDsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
ptrCmdList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle); // RTV Handle works
ptrCmdList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, NULL);
我的对线状态的D3D12_DEPTH_STENCIL_DESC
描述符设置如下
D3D12_DEPTH_STENCIL_DESC depthDesc;
ZeroMemory(&depthDesc, sizeof(D3D12_DEPTH_STENCIL_DESC));
depthDesc.DepthEnable = TRUE;
depthDesc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
depthDesc.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;
depthDesc.StencilEnable = FALSE;
还设置psoDesk.DSVFormat = DXGI_FORMAT_D32_FLOAT;
的DSV格式
视图端口还设置了正确的最小和最大深度值。
我的投影矩阵是静态生成的,并用以下代码上传一次:
DirectX::XMStoreFloat4x4(&m_constBuffer.getPointer()->matView, DirectX::XMMatrixPerspectiveFovLH(DirectX::XM_PIDIV2, (FLOAT)width / (FLOAT)height, 0.5f, 400.0f));
m_constBuffer
是模板类的一个实例,它能够将任何类型的c++类成员作为缓冲区上传到GPU (此处:DirectX::XMFLOAT4X4
)。
我的顶点着色器只是乘以模型矩阵和投影矩阵(目前我没有视图矩阵!)
#include "RootSignature.hlsl"
struct camerCbuf{
float4x4 matProject;
};
struct modellCbuf{
float4x4 matModell;
};
struct sOut{
float4 pos : SV_Position;
float2 tex : TEXCOORD;
};
ConstantBuffer<camerCbuf> constBufferView : register(b0);
ConstantBuffer<modellCbuf> constBufferModell : register(b1);
[RootSignature(ROOTSIG)]
void main(float3 pos : POSITION, float4 tex : TEXCOORD, out sOut outData){
outData.pos = mul(float4(pos.xyz, 1.0f) , constBufferModell.matModell);
outData.pos = mul(outData.pos , constBufferView.matProject);
outData.tex = tex;
}
目前,我不知道为什么我的深度缓冲区不工作。谢谢你提前给我答案!
发布于 2020-08-16 05:47:32
你应该检查一下矩阵。
DirectXMath函数XMMatrixPerspectiveFovLH
返回'row-major‘内存顺序,但是HLSL默认为’列-主要‘,除非您特别指定。请参阅微软
尝试:
XMMATRIX proj = DirectX::XMMatrixPerspectiveFovLH(DirectX::XM_PIDIV2, (FLOAT)width / (FLOAT)height, 0.5f, 400.0f);
DirectX::XMStoreFloat4x4(&m_constBuffer.getPointer()->matView, XMMatrixTranspose(proj));
请注意,您可能会发现使用SimpleMath稍微容易一些。它是DirectX工具包的一部分,用于DX11和DX12。
https://gamedev.stackexchange.com/questions/185100
复制相似问题