OpenGL - 切换着色器

5

我试图理解以下内容:

我有一个对象,我想能够使用两组不同的顶点/片段着色器进行渲染,每个着色器都有它们各自的uniform和纹理,并在这两种设置之间来回切换。(我知道在这种情况下,我可以只使用一个shader,并在其中使用一个uniform来控制运行哪些逻辑,但这是较大项目中的一部分,我无法这样做)

  • 我应该使用一个还是两个gl程序(由glCreateProgram()创建)?
  • 如果我使用两个程序,是否可以放弃未使用的程序并在需要时重新构建它?或者速度太慢了?
  • 如果我只使用一个程序:
    • 我可以在一开始编译着色器吗?
    • 切换时,我应该分离旧的着色器,附加新的着色器并再次链接程序吗?
    • 链接后,我应该重新计算所有uniform的位置吗?
    • 链接后,我应该重新绑定数组缓冲区吗?
    • 我应该执行某些操作以删除先前附加的纹理吗?

创建和链接着色器通常是一个非常缓慢的操作。我建议一开始就简单地创建两个程序,必要时使用它们。要获取更多信息,您需要提供有关您的使用场景的更多详细信息。例如,着色器需要更改的频率。 - BDL
1个回答

4
我应该使用一个还是两个由glCreateProgram()创建的gl程序?
这取决于情况。一个一般的规则是要避免在着色器代码中分支。因此,如果您有两个不同的着色器,适用于2种不同的效果,则编译2个程序并绑定所需的程序。
如果我使用两个程序,将不使用的那个丢弃并在以后需要时重新构建会怎样?或者速度太慢了吗?
这通常是不必要和错误的(除非您有巨大的内存问题)。着色器编译是一个缓慢的过程。更常见的做法是在应用程序启动或第一次需要时编译所有必要的资源,并保持分配并准备好使用。
我可以一次性在开始时编译着色器吗?
可以。
对于所有其他问题:我认为您正在采取错误的方法。
我会说:
- 在启动应用程序时(或需要程序时)编译所有着色器变体。 - 绑定着色器和相关资源,在该着色器中设置统一值后进行绘制。 - 更改着色器时,仅在必要时重新绑定资源或更新统一值。 - 在应用程序结束时释放资源和程序。

我正在将视频输出渲染到我的对象上,所以如果我不在程序中释放未使用的纹理,我有点担心会使用太多资源。这听起来像一个合理的担忧吗?感谢所有其他的评论! - Guig
1
纹理使用的内存与着色器程序本身无关。 - Heisenbug
如果我构建了这两个程序,使用第一个程序附加一个纹理,然后切换到第二个程序,再附加另一个纹理,那么第一个程序中附加的纹理是否会占用内存?还是说这些纹理是与程序上下文无关的? - Guig
内存是通过加载纹理来使用的。这与最终使用它的程序无关。 - Heisenbug

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