我怎样才能标记模板缓冲区中的像素?

我从来没有使用模板缓冲区,直到现在,但我想改变这一点。 我有一个想法应该如何工作:GPU根据给定位置上的模板缓冲区值和一些模板操作丢弃或保持像素着色器之前的光栅化像素。

我不知道的是我将如何标记具有特定值的模板缓冲区中的像素。 例如,我绘制了我的场景,并想要标记用特定材质绘制的所有东西(这种材质可以从纹理中查找,所以理想情况下我应该在像素着色器中标记像素),以便稍后当我做一些后期处理时在我的场景,我只会做标记像素。 除了如何设置模板缓冲区和解释不同的模板操作之外,我没有在网上find任何东西。 我曾经期待在像素着色器中find像SV_Depth这样的System-Value语义(因为模板缓冲区与D3D11中的深度缓冲区共享相同的资源),但MSDN上没有这种东西。 那我该怎么做呢?
如果我误解了一些东西,请帮我明确一点。

有两种方法可以在Direct3D 11中设置模板caching值,其中之一仅在Direct3D 11.3(和Direct3D 12)中可用。 我将把这个答案分成两部分。

Direct3D 11一般

作为D3D11_DEPTH_STENCIL_DESC一部分,您可以指定在模板testing阶段采取何种操作并失败。 这些选项归结为:

  • 保持模板缓冲区中的当前值( D3D11_STENCIL_OP_KEEP
  • 将模板缓冲区中的当前值设置为零( D3D11_STENCIL_OP_ZERO
  • 增加模板缓冲区中的当前值( D3D11_STENCIL_OP_INCR/_SAT
  • 减less模板缓冲区中的当前值( D3D11_STENCIL_OP_DECR/_SAT
  • 将模板缓冲区中的当前值replace为参考值( D3D11_STENCIL_OP_REPLACE

最后一个选项是如何显式地将模板缓冲区索引设置为某个值。

参考值作为OMSetDepthStencilState方法的第二个parameter passing。 请记住,虽然参考值参数采用UINT (32位),但深度网板缓冲区通常只将8位分配给模板部分( DXGI_FORMAT_D24_UNORM_S8_UINT )。

Direct3D 11.3和Direct3D 12

在Direct3D 11.3中,引入了新的着色器语义SV_StencilRef作为像素着色器输出的目标。 有了这个,你可以在每个像素的基础上明确地设置模板缓冲值(而不是每次调用时改变模板参考值)。

对此function的支持可以通过以下方式查询:

 D3D11_FEATURE_DATA_D3D11_OPTIONS2 featuresDescr; ZeroMemory(&featuresDescr, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS2)); d3d11Device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS2, &featuresDescr, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS2)); if(featuresDescr.PSSpecifiedStencilRefSupported) { // SV_StencilRef is supported }