我有一个包含2D覆盖的2D纹理。纹理本身大部分是空白的(透明的),一些部分包含一些数据。
我目前所做的是渲染整个3D场景,禁用深度缓冲区,并在其之上呈现2D四角体:
// render 3D scene
context->OMSetDepthStencilState(_noDepthTestState.Get(), 1); // disable depth test
// render 2D quad on top of the whole viewport
context->OMSetDepthStencilState(nullptr, 1); // restore default_noDepthTestState变量是用以下描述符创建的ID3D11DepthStencilState:
D3D11_DEPTH_STENCIL_DESC desc{};
desc.DepthEnable = false;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
desc.DepthFunc = D3D11_COMPARISON_LESS;
desc.StencilEnable = true;
desc.StencilReadMask = 0xFF;
desc.StencilWriteMask = 0xFF;
desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
desc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
desc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;我想在渲染3D场景之前渲染2D覆盖四,而3D对象将只在2D覆盖为空白的地方绘制。
是否有一个有效的方法来实现这一行为?深度/模具状态的正确配置是什么?
发布于 2021-01-06 12:33:22
这取决于你的主要3D场景的渲染方式。
假设您不使用模具缓冲区,并且使用D3D11_COMPARISON_LESS深度比较,则按以下方式绘制四角体。
你的顶点着色器应该输出四顶点±1,±1,0,1。这使得GUI是最接近相机的,早期的Z拒绝应该在PS阶段之前在3D场景中剪辑被遮挡的像素,从而节省一些GPU资源(我假设这就是为什么您希望呈现2D的第一个)。
您的像素着色器应该从您的图形用户界面纹理读取,比较阿尔法和一些阈值,如果它足够小,调用discard。丢弃的像素不会改变任何缓冲区,无论是颜色还是深度/模板。
如果您的GUI是由轴对齐的矩形组成,或者不使用MSAA,这将正常工作。但是,如果您有图形用户界面的曲线/对角线边,并且使用MSAA,您将不会对结果感到满意。解决这个问题是可能的,但要复杂得多。在呈现图形用户界面纹理时,您需要以某种方式生成每像素的SV_Coverage值。
https://stackoverflow.com/questions/65561807
复制相似问题