使用 OpenGL 和 GLSL 的模板缓冲区和延迟渲染

Stencil buffer and deferred rendering using OpenGL and GLSL

我想知道关于在延迟渲染上下文中使用模板缓冲区的一件事:屏幕上的所有片段着色器 space 是否在 'occluded' 区域内使用?

这是网站 http://www.learnopengl.com/#!Advanced-OpenGL/Stencil-testing 的示例(只是模板缓冲区主题,与延迟渲染无关):

问题:表达式"the others are discarded"在这里是什么意思?这意味着将调用 none 像素着色器,其中掩码采样器中的值为 0,或者对于屏幕上的每个片段,将调用像素着色器,但如果值为是 0 吗?

假设左边第一张图是没有模板缓冲的结果。信息的支持是由 2 个三角形组成的四边形(我们应用延迟渲染技术,因此我们在屏幕上工作 space - 屏幕尺寸为 500x500)。所以在光栅化之后,会调用500 * 500个片段着色器来填充帧缓冲区,即使在没有光线的黑暗区域也会使用它们。这意味着如果我们应用 blinn-phong 着色模型,这最后一个将应用到屏幕上的任何地方,甚至是黑暗区域,我认为这是对性能的浪费。

因此,在这种情况下合乎逻辑的做法应该是创建一个蒙版(使用模板缓冲区或使用外部自定义蒙版渲染通道使用其他帧缓冲区来填充它),最后使用 blinn-phong shading model only for example where the pixel in the value in the mask sampler in screen space is 1. 这样,phong 着色模型将仅在我们的示例中应用于 2 个框和平面!

在第一种方法中正确完成工作的技巧应该是在片段着色器中添加一个条件,以判断我们是否需要根据采样蒙版纹理。

void main(void)
{
    if (texture(MaskSampler, TexCoord.xy).r == 1.0f)
    {
         //Execute here Blinn-Phing shading model...
    }
    //Else nothing
}

但我想知道(如果我们看上面的第三张图片)是否可以告诉 OpenGL API 调用仅与彩色区域相关的片段着色器! (这意味着我们不进入片段着色器的主体)。在这种情况下,使用的片段着色器的数量将大大减少,并且性能会更好!或者唯一的解决方案是像我上面提到的那样在片段着色器中放置一个条件?

在大多数情况下,模板测试将 运行 在片段着色器之前,并跳过它的执行。它被详细描述 here,以及为什么它可能不会在片段着色器之前执行的条件,尽管这些在您描述的设置中不太可能。这比片段着色器中的附加 branches/samples 更受欢迎。它也更容易实施和维护。

但是,在分支的情况下,您提出的运行宁一个不那么复杂的着色器的方法可能也提供了一个加速(超过说运行为每个像素设置完整的着色器)。这是因为,大多数现代驱动程序都优化了空间相干性的分支预测。这意味着,如果局部区域中的所有像素始终采用相同的分支,则可以对此进行优化。 GPU Gems 中的一章描述了这个过程。当然,这在很大程度上取决于着色器的复杂性、面积和驱动程序实现。模版法方法不那么模糊。