这不是OpenGL在没有几何着色器的情况下所做的吗?
不,不是。GS是可选步骤,而不是默认步骤。
为了使OpenGL执行几何着色器,它必须执行所谓的“ 原始程序集 ”。当您通过渲染一系列三角形时GL_TRIANGLE_STRIP
,OpenGL会进行内部处理,将每3个相邻的顶点转换为一个单独的三角形,并适当地修改缠绕顺序。
通常,当不使用GS时,此过程执行一次。但是,当您使用GS时,必须在GS执行之前执行它。但是它也必须在 GS 之后执行,因为GS可以输出完全不同的原始类型(例如,四边形)。
因此,现在您要使系统基本上不做任何额外的工作。毕竟,OpenGL无法假设您的GS没有执行任何操作(这是无法确定的问题)。
此外,存在GS时,许多优化不再起作用。考虑索引渲染。
来自元素数组缓冲区的每个索引将从顶点着色器产生相同的输出。因此,GPU通常会将这些输出缓存在T&L后缓存中。如果发现缓存中已存在索引,则不会再次运行VS。它只是从缓存中获取数据。
它是什么”?“它”是…… 原始装配单元。是的,使用GS时会运行两次。索引缓存的东西?它仅适用于GS 的输入。
那么,GS的输出会怎样?好吧,这取决于硬件。但是它必须进入某种内存缓冲区。问题就在这里:那个缓冲区根本没有索引。这就像glDrawArrays的情况。
因此,如果您发送的索引缓冲区0, 1, 2, 0, 2, 3
,则会在T&L后缓存中转换为4个顶点。但是,GS后顶点的缓冲区现在有6个顶点。GS后缓冲区占用更多空间。因此,如果您遇到无法正确创建T&L优化后的三角形列表或条带的麻烦,并且像您那样翻转了直通GS,则基本上可以消除这种优化带来的一半性能提升。
这不是没有用,但确实很痛。
此外,许多GL 3.x级GPU(又称DX10)具有较小的GS后缓冲区。缓冲区越小,您可以同时激活的GS调用就越少。因此,您的硬件实际上是GS的瓶颈。由于镶嵌是4.x类硬件的一大功能,因此大多数此类硬件具有足以使较重的GS使用可行的缓冲区。
因此,使用GS更可能使您的代码顶点处理成为瓶颈。当然,您总是可以通过使顶点着色器和片段着色器更加复杂来利用它,因为这在当时只是免费的性能。
有关GS引起的减速的更多信息,请阅读本文。
这是关于GS的基本经验法则:永远不要使用GS,因为您认为它会加快渲染速度。当它使您想做的事情成为可能时,应该使用它。如果您想做的是优化,请使用其他方法。
一般的例外情况是: