【问题标题】:Stencil buffer and deferred rendering using OpenGL and GLSL使用 OpenGL 和 GLSL 的模板缓冲区和延迟渲染
【发布时间】:2015-06-05 22:35:23
【问题描述】:

我想知道关于在延迟渲染上下文中使用模板缓冲区的一件事:屏幕空间上的所有片段着色器是否都在“被遮挡”区域内使用?

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

问题:这里的“其他人被丢弃”是什么意思?这意味着在掩码采样器中的值为 0 的情况下不会调用任何像素着色器,或者对于屏幕上的每个片段,将调用像素着色器但如果值为 0,则将应用一个条件丢弃像素的填充?

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

因此,在这种情况下,合乎逻辑的做法应该是创建一个遮罩(使用模板缓冲区或使用外部自定义遮罩渲染通道,使用其他帧缓冲区来填充它),最后使用 blinn-phong 着色模型仅适用于屏幕空间中掩码采样器中的像素值为 1 的示例。这样,phong 着色模型将仅在我们的示例中应用于 2 个框和平面!

在第一种方法中正确完成工作的技巧应该是在片段着色器中添加一个条件,以判断我们是否需要根据采样掩码的值计算当前片段的 blinn-phong 着色纹理。

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

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

【问题讨论】:

  • 我认为检查像素的状态会增加开销,而不是简单地对位进行或运算。您的 GPU 正在并行处理您的整个区域,因此您已经在处理该像素。添加 if 条件将比仅执行按位 OR 增加更多循环。
  • 我怎样才能对位进行或运算?因此,在我的示例中,您在所有情况下都维护将调用 500 * 500 像素着色器的每一帧?如果我使用模板缓冲区,即使是在黑暗区域的那些?
  • 假设您提供的图像中的场景仅由一个平面和两个盒子组成,[几乎]没有资源浪费在绘制黑暗区域,因为那里没有绘制任何内容。此外,在大多数情况下,找出不应用光照计算并有选择地应用它会比在任何地方应用它对性能的影响更大。
  • 顺便说一句,实际上有两种方法可以做到这一点。模板测试可以在片段着色器运行(传统)之后实现,或者在某些硬件(几乎任何现代硬件)上实现,模板测试可能在片段着色器运行之前发生,然后如果测试失败则完全跳过它。描述的第一种方法不会提高性能,也不会向片段着色器添加条件以丢弃。
  • 我说你获得任何东西的可能性很小,尤其是在幼稚的实现中。为您的具体案例实施、分析、做出决定。请注意,着色器中的分支指令通常会带来明显的性能影响(即,它的运行速度会像两个分支都已执行一样慢)。

标签: opengl glsl deferred-rendering deferred-shading


【解决方案1】:

在大多数情况下,模板测试将在片段着色器之前运行,并跳过其执行。它详细描述了here,以及为什么它可能无法在片段着色器之前执行的条件,尽管这些在您描述的设置中不太可能。这将比片段着色器中的其他分支/样本更可取。它也更容易实现和维护。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-17
    • 1970-01-01
    • 2012-04-08
    相关资源
    最近更新 更多