首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在渲染3D场景之前在3D场景之上呈现一个2D UI?

如何在渲染3D场景之前在3D场景之上呈现一个2D UI?
EN

Stack Overflow用户
提问于 2021-01-04 11:18:21
回答 1查看 237关注 0票数 0

我有一个包含2D覆盖的2D纹理。纹理本身大部分是空白的(透明的),一些部分包含一些数据。

我目前所做的是渲染整个3D场景,禁用深度缓冲区,并在其之上呈现2D四角体:

代码语言:javascript
复制
 // 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

代码语言:javascript
复制
   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覆盖为空白的地方绘制。

是否有一个有效的方法来实现这一行为?深度/模具状态的正确配置是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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值。

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

https://stackoverflow.com/questions/65561807

复制
相关文章

相似问题

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