片段着色器中的丢弃是否会阻止对模板缓冲区的修改?

Mr.*_*ith 1 opengl stencil-buffer opengl-4

我想discard在我的片段着色器中阻止该片段写入模板缓冲区;我对游戏中的视觉效果有一个想法,如果我可以依赖该行为,那么它可能是可以实现的discard

我的片段着色器没有做任何非常奇特的事情;它只是对纹理进行采样,如果 alpha 接近 0,则discard否则写入。

void main()
{
    vec4 texColor = texture(tex, texCoord);
    if(texColor.a < 0.5f)
    {
        discard;
    }
    FragColor = texColor;
}
Run Code Online (Sandbox Code Playgroud)

然而,听起来我不能依赖于discard阻止模板缓冲区被写入:

如果模板测试处于活动状态,则丢弃的片段仍会影响模板缓冲区。即使模板或深度测试失败,模板测试也可以修改模板缓冲区。并且由于模板测试发生在深度测试之前,因此深度测试失败不能阻止模板测试更新模板缓冲区。

我确实需要在渲染时激活模板测试。我不能依靠discard阻止写入模板缓冲区吗?

Nic*_*las 5

根据 OpenGL 操作顺序的正常规则,模板测试发生在片段着色器执行之后。因此,执行discard语句的片段着色器将阻止写入帧缓冲区图像。但有一个例外。

该例外是操作顺序可以通过FS 的明确请求来更改。如果没有给出这样的请求,那么事情必须按照原始顺序的定义进行(这就是为什么使用discard 关闭早期片段测试作为优化)。

所讨论的段落正在讨论称为“模板测试”的操作的一部分如何包括潜在地更新模板缓冲区。也就是说,模板测试既可以丢弃片段,又可以根据丢弃的方式更改模板缓冲区的值。这与深度测试不同,深度测试如果失败,则永远不会更新深度缓冲区的值。

  • @Mr.Smith:5 分钟后的反对票只能在编辑帖子后才能撤回(我刚刚做了)。这样做是为了防止竞争性的否决,即您对竞争性答案进行否决以使您的答案更加突出,然后在一段时间后撤回您的否决以恢复 -1。 (2认同)