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

Gam*_*per 5 opengl stencil-buffer

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

例如如果我有以下掩码:

glStencilMask( 0x06);
Run Code Online (Sandbox Code Playgroud)

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

0x06
Run Code Online (Sandbox Code Playgroud)

如果模板操作是GL_INCR_WRAP

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

基本上我有面具:

00000110
Run Code Online (Sandbox Code Playgroud)

和价值

00000110
Run Code Online (Sandbox Code Playgroud)

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

00000010
Run Code Online (Sandbox Code Playgroud)

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

00000000
Run Code Online (Sandbox Code Playgroud)

der*_*ass 4

OpenGL 4.5 核心配置文件规范的第 17.4.2 节“缓冲区更新的精细控制”指出:

这些命令 void StencilMask( uint mask ); void StencilMaskSeparate( enum face, uint mask ); 控制将特定位写入模板平面。的最低有效 s 位mask(其中 s 是模板缓冲区中的位数)指定整数掩码。当此掩码中出现 1 时,将写入模板缓冲区中的相应位;如果出现 0,则表示该位未被写入。

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

第 17.3.5 节“模板测试”指出(我的重点):

为了递增和递减的目的,模板位被视为无符号整数。通过饱和度递增或递减会将模板值限制在 0 和最大可表示值。在不饱和的情况下递增或递减将换行,这样递增最大可表示值会导致 0,递减 0 会导致最大可表示值。

模板掩模本身与管道的该阶段无关。与所有函数一样,它仅在片段最终写入帧缓冲区时应用gl*Mask()

因此,将值0110放入缓冲区并应用GL_INCR_WRAP会导致0111当将其写入缓冲区时,会应用掩码,因此基本上会再次得到0110(而不是 0)。

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

StencilFuncStencilFuncSeparate采用三个参数来控制模板测试是否通过。ref是用于无符号模板比较的整数参考值。模板比较操作和查询将ref其值限制在范围 [0; 2^s - 1],其中 s 是附加到绘制帧缓冲区的模板缓冲区中的位数。的最低有效位mask 与参考值和存储的模板值进行按位与运算,所得掩码值是参与由 控制的比较的值func

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

  • 谢谢,这是一个完美的答案:)所以基本上 `glStencilMask` 只是在写入缓冲区之前屏蔽一个值,而 `glStencilFunc` 的掩码仅在模板测试期间以类似于 `( ref & mask ) 运算符 ( stencil ) 的方式使用和面具)` (2认同)