You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DirectX 11线框视图下能否实现深度测试以遮挡后方物体?

DirectX 11线框视图下深度测试失效问题

我尝试在DirectX 11的线框视图中实现Z缓冲(深度测试)。当光栅化器描述的填充模式设为D3D11_FILL_SOLID时,能得到正确结果:
实体模式效果

对应的光栅化器状态代码:

D3D11_RASTERIZER_DESC rasDesc;
rasDesc.FillMode = D3D11_FILL_SOLID;
rasDesc.CullMode = D3D11_CULL_NONE;
rasDesc.FrontCounterClockwise = true;
rasDesc.DepthClipEnable = true;
rasDesc.DepthBias = 0;
rasDesc.SlopeScaledDepthBias = 0;
rasDesc.DepthBiasClamp = 0;
rasDesc.ScissorEnable = FALSE;
rasDesc.MultisampleEnable = FALSE;
rasDesc.AntialiasedLineEnable = false;
CHECK_ERROR(pDevice->CreateRasterizerState(&rasDesc, &WireFrame));

但将填充模式改为D3D11_FILL_WIREFRAME切换到线框视图后,本该被红色平面遮挡的绿色立方体依然可见:
线框模式效果

以下是完整的深度相关代码:

D3D11_DEPTH_STENCIL_DESC dsDesc = {};
dsDesc.DepthEnable = true;
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D11_COMPARISON_LESS;
Microsoft::WRL::ComPtr<ID3D11DepthStencilState> pDSState;

CHECK_ERROR(pDevice->CreateDepthStencilState(&dsDesc, &pDSState));
pContext->OMSetDepthStencilState(pDSState.Get(),0);

Microsoft::WRL::ComPtr<ID3D11Texture2D> pDepthStencil;
D3D11_TEXTURE2D_DESC descDepth = {};

descDepth.Width = 1022;
descDepth.Height = 574;
descDepth.MipLevels = 1u;
descDepth.ArraySize = 1u;
descDepth.Format = DXGI_FORMAT_D32_FLOAT;
descDepth.SampleDesc.Count = 1u;
descDepth.SampleDesc.Quality = 0u;
descDepth.Usage = D3D11_USAGE_DEFAULT;
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; 
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
CHECK_ERROR(pDevice->CreateTexture2D(&descDepth, nullptr, &pDepthStencil));

D3D11_DEPTH_STENCIL_VIEW_DESC stencil_view_desc;
stencil_view_desc.Flags = 0;
stencil_view_desc.Format = DXGI_FORMAT_D32_FLOAT;
stencil_view_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
stencil_view_desc.Texture2D.MipSlice = 0u;

CHECK_ERROR(pDevice->CreateDepthStencilView(pDepthStencil.Get(), &stencil_view_desc, &pDs));
pContext->OMSetRenderTargets(1, pTarget.GetAddressOf(),pDs.Get());

请问能否在DirectX 11的线框视图下隐藏该绿色立方体?


解决方案

当然可以解决这个问题,你可以从以下几个方向排查修复:

1. 确保渲染顺序正确

深度测试依赖先绘制遮挡物(红色平面),再绘制被遮挡物(绿色立方体)。如果渲染顺序颠倒,线框模式下可能因为深度缓冲被覆盖导致失效,确认先画红色平面再画绿色立方体。

2. 正确清除深度缓冲

每帧渲染开始时必须清除深度缓冲,否则上一帧的深度数据会干扰当前帧测试。添加以下代码:

float clearDepth = 1.0f;
UINT8 clearStencil = 0;
pContext->ClearDepthStencilView(pDs.Get(), D3D11_CLEAR_DEPTH, clearDepth, clearStencil);

3. 调整深度偏差解决Z-fighting

线框模式的光栅化逻辑和实体模式不同,容易出现深度冲突。可以给线框添加轻微的深度偏差,让被遮挡的线框更容易被剔除:

rasDesc.DepthBias = 1;
rasDesc.SlopeScaledDepthBias = 0.1f;

调整后需要重新创建光栅化器状态并设置到设备上下文。

4. 确认关键参数保持开启

你当前已经设置DepthClipEnable = true,这个参数必须始终开启,否则超出视锥体深度范围的像素不会被裁剪,会导致深度测试异常。

按以上步骤调整后,线框模式下的深度测试就能正常工作,绿色立方体被遮挡的部分会被隐藏。

内容的提问来源于stack exchange,提问作者Ayushkr3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 04:45:18