GLSL多个着色程序VS制服开关

时间:2011-06-30 19:02:50

标签: architecture glsl shader

我正在开发着色器管理器架构,我有几个问题需要更高级的人员。 我目前的选择反对两个设计:


1。每个材质着色器程序

=>为程序中使用的每种材料创建一个着色器程序。

潜在利弊:

  • 考虑到每个对象可能都有自己的材质,它涉及很多glUseProgram调用。
  • 意味着创建了许多着色器程序对象。
  • 更复杂的架构#2。

优点:

  • 可以为材质中使用的每个“选项”专门生成着色器代码。
  • 如果我没错,制服必须只设置一次(创建着色器程序时)。


2。全局着色器程序

=>为每个着色器功能(闪电,反射,视差映射......)创建一个着色器程序,并根据要渲染的材质使用配置变量启用或放弃选项。

潜在利弊:

  • 每帧必须多次更换制服。

优点:

  • 较低的着色器程序计数。
  • 减少SP swich(glUseProgram)。

你可能会注意到我目前的倾向是#1,但我想知道你对它的看法。

  • 初始制服设置是否会抵消glUseProgram呼叫开销(我不是特别速度怪胎)?
  • 在#1的情况下,对于任何内存或性能考虑,我应该在创建SP时只调用一次glLinkProgram,还是每次调用glUseProgram时都必须取消链接/链接?
  • 有更好的解决方案吗?

谢谢!

3 个答案:

答案 0 :(得分:11)

让我们看看#1:

  

考虑到每个对象可能都有自己的材质,它涉及很多glUseProgram调用。

真的,这不是什么大不了的事。交换程序很难,但你也要交换纹理,所以它不像你还没有改变重要的状态。

  

意味着创建了许多着色器程序对象。

这会受到伤害。实际上,#1的主要问题是着色器的爆炸性组合。虽然ARB_separate_program_objects会有所帮助,但它仍然意味着你必须编写很多着色器,或者想出一种不写很多着色器的方法。

或者您可以使用deferred rendering,这有助于缓解此问题。其众多优点之一是它将材料数据的生成与将该材料数据转换为光反射(颜色)的计算分开。因此,您可以使用更少的着色器。您有一组生成材质数据的着色器,以及一个使用材质数据进行光照计算的集合。

所以我想说#1使用延迟渲染。

答案 1 :(得分:9)

这实际上取决于您的硬件和应用的具体要求。

#2的另一个问题是你的着色器通常最终效率不高,因为它必须根据你传入的制服进行一些条件分支。所以你基本上在较少的时间切换状态与减少的吞吐量之间进行权衡在你的着色器中。这取决于哪一个更糟糕。

每个着色器一定只能调用一次glLinkProgram。编译着色器比切换已编译的着色器需要更长的时间。

实际上没有更好的解决方案。几乎所有编写渲染引擎的人都必须做出你所面临的决定。

答案 2 :(得分:1)

在移动设备上,着色器中的分支会大大增加渲染时间。您应该测量切换程序的时间与每个顶点/每个纹素重复操作中与分支相关联的降低的绘制速率。我推荐方法#1,看看如何为一个好的oop友好着色器架构设置GPUImage。

https://github.com/BradLarson/GPUImage

相关问题