在OpenGL引擎中组织GLSL着色器

哪个更好 ?

  1. 要有一个着色器程序有很多制服指定要使用的灯光或映射(例如,我需要一个网格是视差映射,另一个视差/镜面映射)。 如果需要的话,我会制作一个caching的制服清单,然后为每一个下一个网格制作一些制服。

  2. 为了每个需要的情况都有很多的着色器程序 ,每一个都有less量的制服,如果需要的话,为每个网格做glUseProgram的惰性绑定。 在这里,我假定网格是正确的批处理,以避免冗余交换机。

我所知道的大多数现代引擎都有一个“着色器caching”,并使用第二个选项,因为显然它更快。

你也可以看看允许dynamic链接的ARB_shader_subroutine。 但是我认为它只适用于DX11类硬件。

一般来说,选项2会更快/更好,除非你有一个真正庞大的节目数量。 您还可以使用跨程序共享的缓冲区对象,以便在更改程序时不需要重置任何值。

另外,一旦链接了一个程序,就可以将所链接的所有着色器都释放到程序中。 这将释放所有的源代码和驱动程序所保留的任何预链接信息,只将完全链接的程序留在内存中。

我倾向于认为这取决于具体的应用。 是的,因为说100个节目,每个节目每个人可能有大约2-16个制服, 两者之间的交易可能会更好。 我会倾向于认为,对于你最常用的阴影技术,说10到20个程序就足够了,或者更多。 例如,你可能想要一个程序/着色器来做所有的凹凸贴图,一个做你所有的雾效果,一个做reflection,一个做折射。

现在在你的问题的范围之外,我认为它也适用于这里,将一个东西join你的引擎将是一个BatchProcess和BatchManager类的设置,以减less总线上的CPU – GPU调用的数量,因为这将certificate是有效的。 我不认为有一个适合所有问题的解决scheme,因为我相信这将是特定于应用程序的,就像设置引擎的顶点(原语)的数量(桶)与多less这些批次中的每一个都包含顶点。

为了使这个更清楚一点:一个游戏可能有4个容器或批次,其中每个批次可以容纳多达10,000个顶点,在BatchManager决定清空将所有这些顶点发送到graphics卡之前的桶渲染pipe道将被处理和绘制,其中不同的游戏可能具有10个具有5,000个顶点的桶,或者另一个游戏可能具有8个具有12,0000个顶点的桶。

所以可能会根据你的需要进行交换。 如果你有一个单一的scheme与100的制服; 单个程序在stream水线中更容易pipe理,但是着色器在读取和pipe理上会过于繁琐。 然后再次使用几乎没有制服的着色器是很容易阅读和pipe理,但有100个程序是有点难以pipe理的CPU之前,链接和发送他们正确渲染。 我个人会试图find一个中间的地方,我有足够的程序来完成每一个完全独一无二的具体任务,比如在一个地方做雾密度,在另一个地方做一个体积阴影贴图,每个程序都有足够的制服去做所需的计算。

下一步就是做一些基准testing,看看你的效率和开销是否平衡,做出适当的调整。