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

use*_*657 1 c++ opengl glsl sprite vertex-shader

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

    5    3, 4
     *---*
     |  /|
     |/  |
     *---* 
  1, 6    2
Run Code Online (Sandbox Code Playgroud)

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

现在我的问题是,有没有更好的方法来做到这一点实际上比做所有额外的顶点着色器操作更快.

Mat*_*jek 5

不需要几何着色器.

你需要的是索引渲染:每个顶点只存储在VBO中一次.然后,创建另外的缓冲区对象(绑定GL_ELEMENT_ARRAY_BUFFER),用于存储实际VBO 中存储的顶点索引.

可视化:(来源:in2gpu.com)

在此输入图像描述

请注意,在您的情况下并没有那么糟糕.例如,考虑绘制一个圆圈:假设您使用360个三角形绘制它(似乎合理).在这种情况下,中心顶点将为每个三角形重复 - 这将导致359*4(组件数+对齐)*4(通常值sizeof(float))= 5744字节的不必要数据:

在此输入图像描述

进一步阅读:


UPDATE

由于在此形成中重复了2个顶点,因此顶点着色器执行相同计算的两倍.

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

所以不要优化它.如果你知道索引渲染,但你要么不能使用它,要么它没有任何改进,让GPU尽可能地渲染.