在Direct3D中使用模板缓冲区

N.R*_*abh 1 textures direct3d stencil-buffer

我正在尝试使用模板缓冲区ID3D11Texture2D来覆盖另一个纹理上的一个纹理的一部分.我计划通过在模板缓冲区上绘制所需的形状然后复制纹理来完成此操作.请提供一些有关2D纹理示例代码的优秀教程,以学习模板缓冲区的使用.(或其他一些方法)

Zon*_*ner 14

模板面具101:

  • 所有主流GPU都使用8位模板缓冲区,并且它们与深度缓冲区相连,因此您必须选择包含模板的缓冲区格式(主要是D24S8)
  • 每帧开始时都有清晰的深度和模板,以避免帧间性能问题*(见下面的注释)
  • 除非您知道自己在做什么,否则始终使用0xFF作为读写掩码.
  • 出于性能原因,在进行模板读取测试时没有启用深度写入
  • 出于性能原因,如果可能的话,将模板读取测试限制在== 0和!= 0,并清零
  • 如果您正在使用D3D9,您可以使用剪刀组合清除模板缓冲区,这比手动渲染四元组以将缓冲区设置回零要快得多.
  • 无法在着色器中访问模板信息,因此后处理效果无法确定相邻像素的模板状态,而掩模也不在正常的渲染目标中并作为纹理采样.
  • 可以从以下条件修改模板缓冲区值:
    1. 模板测试失败
    2. 深度测试失败了
    3. 模板和深度测试都通过了
  • 无论哪种条件首先决定动作,都可以
    1. 保持(单独保留模板值)
    2. 替换(用'stencilref'值替换模板值)
    3. 递增(将1添加到当前缓冲区)
    4. 减量(模板缓冲区中的子1)
    5. 零(将值设置为直接为零,当其他条件之一需要使用当前的stencilref值时非常有用)

*未遵循大多数这些规则通常会导致模板性能最差:您的像素着色器针对每个像素执行,而不会对模板蒙板像素执行早期拒绝.此外,对于较旧的Geforce卡,这也可能导致所有后续绘制调用的早期深度拒绝中断,在下一帧或深度缓冲区和模板被清除之前不会修复.

模板蒙版实际上很容易生成:

  • 清除模板缓冲区
  • 为模板写入启用模板状态(使用stencilref 1或'increment'代替'keep''替换')
  • 绘制一个多边形.请注意,在着色器中使用"discard"将阻止模板更新,这是将纹理加载到模板缓冲区中的方式(但仅作为二进制掩码)

  • 禁用模板写入,启用模板测试

  • (理想情况下)也禁用深度写入
  • 绘制需要模板遮罩的效果