OpenGL程序管线对象的正确使用/目的

4
使用OpenGL 4.1和ARB_separate_shader_objects,我们能够将着色管线的不同阶段存储在着色器程序中。如我们所知,要使用它们,我们需要将它们附加到一个程序管线对象上,然后绑定该对象。
我的问题是,为什么我们需要程序管线对象呢?在我的渲染器中,我只有一个这样的对象,并且我更改它的附件以更改着色器。我想不出任何情况下你会真正想要多个这样的对象。如果您存储许多管线对象,每个对象包含不同的着色器程序组合,那么事情变得比根本不使用分离着色器还要混乱。
那么,管线对象的目的是什么?更改附件(是否)比绑定不同的管线对象更昂贵?规范为什么要这样做,而不是像glUseProgram一样操作glUseProgramStages?
2个回答

6
管线对象存在的主要原因是将程序对象中的各个阶段链接在一起确实具有某些优点。例如,有许多着色器阶段间的互操作验证规则。如果单独的程序序列无效,则需要提醒用户。
当使用将所有阶段链接在一起的程序时,您可以在链接时检测到这些验证失败。所有这些测试只会 一次 进行,不会再有其他测试。
如果让“glUseProgramStages与glUseProgram的操作方式相同”,那么每次使用新的着色器集合进行渲染时,系统都必须进行阶段间验证测试。管线表示缓存此类测试的便捷方法。如果只设置管线的程序并且在此后从未修改过,则管线的验证结果永远不会改变。因此,验证仅会发生一次,就像对多阶段程序一样。
另一个问题是,在将某些程序关联到彼此时,实现可能需要执行一些次要的着色器修复工作。管线对象表示缓存此类修复工作的便捷位置。如果没有它们,则每次更改着色器时都必须执行这些修复工作。

1

为什么我们需要程序管线对象?

我们不需要程序管线对象,它们是纯粹可选的。对于正在使用的每个着色器组合使用一个程序对象是最简单和最常见的方法。

那么,管线对象的目的是什么?

根据https://www.opengl.org/registry/specs/ARB/separate_shader_objects.txt:

许多开发人员围绕混搭方法构建他们的着色器内容,其中可以使用单个顶点着色器与多个片段着色器(或反之亦然)。此扩展采用了GLSL的“混搭”着色器阶段模型,允许将多个不同的GLSL程序对象绑定到各自的渲染管线阶段,而与其他阶段绑定无关。这允许程序对象仅包含最适合应用程序需求的着色器阶段。


看来你完全误解了我的问题。我不是在问分离着色器对象的原因。只是管线对象需要能够使用它们。 - Jagoly
好的,抱歉我仍然不理解你的问题。 - dari
那么,您会如何配置特定的完整流水线呢?您是更倾向于“绑定”各个部分,还是创建一个引用它们并可以一次性设置整个管道的对象呢? - peppe
这就是我的观点:那真的一点也不有帮助。如果您像那样存储管线对象,那么为什么还要使用单独的着色器呢?仅为某些组合存储管线将是不一致的,但为所有组合存储它们将会失去首先分离着色器的目的。 - Jagoly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接