根据模板操作,掩码如何影响模板值?

How does mask affect stencil value according to stencil op?

OpenGL 参考 pdf 中的文档(OpenGL 3.3 和 4.5 规范)并不清楚应用遮罩时存储的模板值会发生什么。

例如,如果我有以下掩码:

glStencilMask( 0x06);

并且存储在模板缓冲区中已经有这个值:

0x06

如果模板操作是GL_INCR_WRAP

当在该像素上正确调用 StencilOp 时会发生什么?

基本上我有面具:

00000110

和价值

00000110

我尝试增加它,它是否被包裹了?

00000010

或者它只是归零了? (00000110 + 1) & mask

00000000

OpenGL 4.5 core profile specification 的第 17.4.2 节 "Fine Control of Buffer Updates" 指出:

The commands void StencilMask( uint mask ); void StencilMaskSeparate( enum face, uint mask ); control the writing of particular bits into the stencil planes. The least significant s bits of mask, where s is the number of bits in the stencil buffer, specify an integer mask. Where a 1 appears in this mask, the corresponding bit in the stencil buffer is written; where a 0 appears, the bit is not written.

glStencilMask() 参数控制哪些位平面写入 到模板缓冲区。它不控制读取的内容或 glStencilOp 的操作方式。

第 17.3.5 节 "Stencil Test" 指出(我强调):

For purposes of increment and decrement, the stencil bits are considered as an unsigned integer. Incrementing or decrementing with saturation clamps the stencil value at 0 and the maximum representable value. Incrementing or decrementing without saturation will wrap such that incrementing the maximum representable value results in 0, and decrementing 0 results in the maximum representable value.

模板掩码本身与流水线的那个阶段无关。它仅在片段最终写入帧缓冲区时应用,就像所有 gl*Mask() 函数一样。

所以在缓冲区中有值 0110 并应用 GL_INCR_WRAP 导致 0111 并且当它被写入缓冲区时,应用掩码,所以你基本上结束了0110 再次(而不是 0)。

另请注意,glStencilFunc() 中还有一个 mask 参数,用于定义在模板测试之前应用的位掩码。再次引用第 17.3.5 节:(我的重点):

StencilFunc and StencilFuncSeparate take three arguments that control whether the stencil test passes or fails. ref is an integer reference value that is used in the unsigned stencil comparison. Stencil comparison operations and queries of ref clamp its value to the range [0; 2^s - 1], where s is the number of bits in the stencil buffer attached to the draw framebuffer. The s least significant bits of mask are bitwise ANDed with both the reference and the stored stencil value, and the resulting masked values are those that participate in the comparison controlled by func.

因此,如果您想以某个值 2^n-1 环绕 a,您可以简单地忽略模板缓冲区中的额外位,并在模板测试中测试这些位。