【问题标题】:OpenGL - switch shadersOpenGL - 切换着色器
【发布时间】:2016-09-28 18:16:10
【问题描述】:

我正在努力解决以下问题:

我有一个对象,我希望能够使用两组不同的顶点/片段着色器进行渲染,每个着色器都有自己的制服和纹理,并在这两个设置之间来回切换。 (我知道在这种情况下,我可以只有一个着色器,它有一个统一的指令来运行哪个逻辑,但这是我无法做到的更大事情的一部分)

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

【问题讨论】:

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

标签: opengl opengl-es shader


【解决方案1】:

我应该使用一个还是两个 gl 程序(由 glCreateProgram() 创建)?

视情况而定。一般规则是避免在着色器代码内部分支。因此,如果您有 2 个不同的着色器,对于 2 个不同的效果,只需编译 2 个程序并绑定所需的一个即可。

如果我使用两个程序,是否可以丢弃未使用的程序, 并在以后需要时重建它?还是太慢了?

这通常是不需要的并且是错误的(也许除非你有巨大的内存问题)。着色器编译是一个缓慢的过程。

更常见的做法是在应用程序启动时或第一次需要时编译所有必要的资源,然后将它们分配并准备好使用。

我可以在开始时只编译一次着色器吗?

是的。

对于剩下的所有问题:我认为您采取了错误的方法。

我会说:

  • 在开始时(或在需要程序时)编译所有着色器变体
  • 绑定着色器和相关资源,在使用该着色器绘制之前设置制服。
  • 更改着色器时,仅在不同且需要时重新绑定资源或更新统一值
  • 在应用程序结束时释放资源和程序

【讨论】:

  • 我正在将视频输出渲染到我的对象,所以如果我不释放程序中没有使用的纹理,我有点担心会占用太多资源。这听起来像一个合理的担忧吗?感谢所有其他 cmets!
  • 纹理使用的内存与着色器程序本身无关。
  • 好的,但是如果我构建两个程序,使用第一个程序,附加纹理,切换到第二个程序,附加另一个纹理,我是否将内存用于程序中附加的第一个纹理不曾用过?还是纹理独立于程序上下文?
  • 内存用于加载纹理。它与最终使用它的程序无关。
猜你喜欢
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
  • 2017-04-08
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多