GLSL / OpenGL 重用顶点着色器的输出

GLSL / OpenGL Reusing output from vertex shader

我正在 3d 中渲染精灵 space,其中每个四边形由两个三角形组成。我画 GL_TRIANGLES(见下文)。由于在此构造中重复了 2 个顶点,因此顶点着色器执行两次相同的计算。

    5    3, 4
     *---*
     |  /|
     |/  |
     *---* 
  1, 6    2

我想通过使用几何着色器重复这两个顶点来优化它。这样做的原因是顶点着色器很昂贵并且场景中有大量三角形。经过大量的 hackery,我设法实现了它。它关闭后效率非常低。它在我的机器上实际上慢了 45%。我假设这是因为原始装配执行了两次,并且在几何着色器中发生了很多不必要的数据复制。我无法查看汇编代码,所以我只能猜测。

现在回答我的问题,是否有更好的方法可以比执行所有额外的顶点着色器操作更快。

不需要几何着色器。

您需要的是索引渲染:每个顶点仅在 VBO 中存储一次一次。然后,您创建额外的缓冲区对象(与 GL_ELEMENT_ARRAY_BUFFER 绑定),该对象存储实际 VBO 中存储的顶点的 索引

可视化:(来源:in2gpu.com

请注意,您的情况 并不坏。例如,考虑画一个圆:比方说,您使用 360 度三角形绘制它(看起来很合理)。在这种情况下,每个三角形的中心顶点都会重复 - 这将导致 359 * 4(组件数 + 对齐)* 4(sizeof(float) 的通常值)= 5744 字节的不必要数据:

进一步阅读:


更新

Since 2 vertices are repeated in this formation, vertex shader does two times the same computation.

不,肯定不是。所有重复的顶点肯定会命中顶点缓存(我猜这就是你所说的 "caching" 的意思?)并会被重用。这是一种非常常见的使用模式 - 请记住,有时索引渲染不是解决方案(例如,当您对同一位置有不同的属性时 - 是的,您可以将位置数据移动到单独的 VBO,但通常不值得这样做,所以让我们离开),因此 GPU 必须有效地处理这种情况。 GPU 供应商解决了这个问题。

所以不要优化它。如果您知道索引渲染,但您不能使用它或者它没有提供任何改进,让 GPU 以尽可能最好的方式处理渲染。

Since 2 vertices are repeated in this formation, vertex shader does two times the same computation.

不,实际上所有现有的实现(即 GPU)都没有。

重复的顶点将命中顶点缓存,并且先前在同一顶点上计算的现有结果仅在管道中的以下步骤中重复使用。

尝试优化这是一个有争议的问题,GPU 已经针对系统被榨干的使用模式和性能进行了优化。