gl_FragColor 如何影响模板缓冲区?

Posted

技术标签:

【中文标题】gl_FragColor 如何影响模板缓冲区?【英文标题】:How does gl_FragColor affect the stencil buffer? 【发布时间】:2017-01-19 17:48:26 【问题描述】:

我已经设置了绘制到模板缓冲区的操作,类似于以下内容:

void onDisplay() 
  glClear(GL_DEPTH_BUFFER_BIT);
  glEnable(GL_STENCIL_TEST);
  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  glDepthMask(GL_FALSE);
  glStencilFunc(GL_NEVER, 1, 0xFF);
  glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);

  // Draw to stencil buffer
  glStencilMask(0xFF);
  glClear(GL_STENCIL_BUFFER_BIT);  // needs mask=0xFF
  draw_circle();

  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  glDepthMask(GL_TRUE);
  glStencilMask(0x00);

  // draw where stencil's value is 0
  glStencilFunc(GL_EQUAL, 0, 0xFF);
  /* (nothing to draw) */
  // draw only where stencil's value is 1
  glStencilFunc(GL_EQUAL, 1, 0xFF);

  draw_scene();

  glDisable(GL_STENCIL_TEST);

现在,如果我在调用draw_circle()(上图)时启用了以下片段着色器:

void main() 
  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);

如果我使用以下片段着色器,模板缓冲区的值会有什么不同?

void main() 
  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);

换句话说,我想知道在绘制到模板缓冲区时,片段着色器的输出如何影响模板缓冲区。

编辑

我的问题的重点是纠正我对模板缓冲区的一些误解。我认为可以很好地解释模板缓冲区的一个示例是 [1]。这里提到了以下几点:

glColorMask 函数允许您指定在绘图操作期间将哪些数据写入颜色缓冲区。在这种情况下,您需要禁用所有颜色通道(红色、绿色、蓝色、alpha)。写入深度缓冲区也需要使用 glDepthMask 单独禁用,以便立方体绘制操作不会受到矩形剩余深度值的影响。这比稍后简单地再次清除深度缓冲区更干净。

所以,从这个页面看来,为了写入模板缓冲区,需要启用/禁用适当的模式(即颜色和深度),然后通过 整个光栅化过程,它只会写入模板缓冲区。由于光栅化过程包括片段着色器,片段着色器的输出(即gl_FragColor)会被忽略吗?如何告诉 GL 什么 写入模板缓冲区位置(x, y)

[1]:https://open.gl/depthstencils

【问题讨论】:

【参考方案1】:

除非您有权访问 AMD/ARB_shader_stencil_export,否则片段着色器不能直接影响到模板缓冲区的输出。唯一的例外是discarding 片段。

根据this database,只有 AMD 卡提供此扩展。此外,该扩展还公开了专门用于模板的输出。它修改the stencil value of the fragment;片段的颜色值永远不会影响片段的模板值。

【讨论】:

嗯...我想知道是否可以以某种方式渲染为 R8UI 纹理并将其作为 STENCIL_INDEX8 读回。 (我猜这需要对规范进行创造性的解释)。 @peppe:不。你甚至不能在颜色和模板纹理之间复制(在 GPU 上)。您必须先复制到 CPU 内存,然后再将其复制回 GPU 内存。 嗯,我想我的问题可能并不完全清楚。为了写入模板缓冲区,您不需要经过整个光栅化管道,包括片段着色器吗?所以,我想知道,在绘制到模板缓冲区时,片段着色器的输出(即 gl_FragColor)是否会影响模板缓冲区? 你不能以直接的方式做到这一点(没有上面提到的扩展)。是的,您需要完整的光栅化管道来写入模板缓冲区,但是您可以在其中写入的内容非常有限,并且只能由glStencilOp 控制——基本上,非常简单的整数运算。为什么需要如此复杂的模板缓冲区填充? @NicolBolas 我明白了。我的问题对我想要的答案不够清楚。佩佩告诉我我真正想知道的。我会提高你的答案。如果我能接受两个答案,我会接受,但我觉得 peppe 在学习我想要学习的内容方面给了我更多帮助。

以上是关于gl_FragColor 如何影响模板缓冲区?的主要内容,如果未能解决你的问题,请参考以下文章

使用gl_FragColor与输出vec4颜色?

gl_FragColor 值是不是应该标准化?

FineReport中如何对cpt模板加密

OpenGL更新缓冲区如何影响速度

OpenGL如何在模板测试失败且深度测试成功时写入模板缓冲区?

webGL - 如何在帧缓冲区旁边设置模板缓冲区并使用它?