我正在研究着色器管理器架构,我有几个问题需要向更高级的人员询问。 我当前的选择反对两种设计:
1。每个 Material 着色器程序
=> 为程序中使用的每种 Material 创建一个着色器程序。潜在缺点:
- 考虑到每个对象可能都有自己的 Material ,因此涉及大量 glUseProgram 调用。
- 意味着创建大量着色器程序对象。
- 比 #2 更复杂的架构。
优点:
- 可以专门为 Material 中使用的每个“选项”生成着色器代码。
- 如果我没记错的话,制服只需设置一次(在创建着色器程序时)。
2.全局着色器程序
=> 为每个着色器功能(闪电、反射、视差映射...)创建一个着色器程序,并使用配置变量根据要渲染的 Material 启用或放弃选项。潜在缺点:
- 每帧必须多次更换制服。
优点:
- 减少着色器程序数量。
- 减少 SP 开关 (glUseProgram)。
您可能会注意到我目前的倾向是#1,但我想知道您对此的看法。
- 初始制服设置是否会抵消 glUseProgram 调用开销(我不是特别速度狂)?
- 在情况 #1 中,出于内存或性能考虑,我应该在创建 SP 时仅调用一次 glLinkProgram,还是每次调用 glUseProgram 时都必须取消链接/链接?
- 有更好的解决方案吗?
谢谢!
最佳答案
让我们看看#1:
Considering every object might have its own material, it involves a lot of glUseProgram calls.
这其实没什么大不了的。交换程序很困难,但你也会交换纹理,所以这并不是说你还没有改变重要的状态。
Implies the creation of a lot of shaderprogram objects.
这会很痛。事实上,#1 的主要问题是着色器的爆炸性组合。虽然 ARB_separate_program_objects 会有所帮助,但它仍然意味着您必须编写大量着色器,或者想出一种不编写大量着色器的方法。
或者您可以使用deferred rendering ,这有助于缓解这种情况。其众多优点之一是它将 Material 数据的生成与将该 Material 数据转换为光反射率(颜色)的计算分开。因此,您可以使用的着色器要少得多。您有一组生成 Material 数据的着色器,以及一组使用 Material 数据进行光照计算的着色器。
所以我会说使用 #1 和延迟渲染。
关于architecture - GLSL 多个着色器程序 VS 制服开关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6539774/