首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在DirectX 12中使用深度缓冲区

如何在DirectX 12中使用深度缓冲区
EN

Game Development用户
提问于 2020-08-13 14:07:16
回答 1查看 2.1K关注 0票数 0

简单地说:我试图在D3D12中绑定和使用深度缓冲区,但它不起作用。深度缓冲区被正确地创建和绑定(我可以在nsight图形中看到它),但是只需要0.0f或1.0f (清除值)。我最初认为这可能是我的投影矩阵的问题,所以我在附近和远的Z玩,但我没有得到任何改进。

以下代码用于创建深度缓冲区:

代码语言:javascript
运行
复制
// === 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方法中,执行以下代码

代码语言:javascript
运行
复制
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描述符设置如下

代码语言:javascript
运行
复制
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格式

视图端口还设置了正确的最小和最大深度值。

我的投影矩阵是静态生成的,并用以下代码上传一次:

代码语言:javascript
运行
复制
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)。

我的顶点着色器只是乘以模型矩阵和投影矩阵(目前我没有视图矩阵!)

代码语言:javascript
运行
复制
#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;
}

目前,我不知道为什么我的深度缓冲区不工作。谢谢你提前给我答案!

EN

回答 1

Game Development用户

回答已采纳

发布于 2020-08-16 05:47:32

你应该检查一下矩阵。

DirectXMath函数XMMatrixPerspectiveFovLH返回'row-major‘内存顺序,但是HLSL默认为’列-主要‘,除非您特别指定。请参阅微软

尝试:

代码语言:javascript
运行
复制
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工具包的一部分,用于DX11DX12

票数 2
EN
页面原文内容由Game Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://gamedev.stackexchange.com/questions/185100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档