OpenGL退化GL_TRIANGLES共享相同的顶点

时间:2015-12-22 19:06:16

标签: c++ opengl glsl vertex-shader

我通过GL_TRIANGLESglDrawElements()的VertexBuffer + IndexBuffer发送到GPU。

在顶点着色器中,我想将一些顶点捕捉到相同的坐标,以便在运行中简化大型网格。 结果我取得了重大的性能提升,因为很多三角形正在崩溃到同一点并且会退化。 但我没有获得任何fps收益。

通过测试我将顶点着色器设置为gl_Position(vec4(0))以退化所有三角形,但仍然没有区别......

是否有任何标记"激活"堕落或我失踪了什么?

glQuery的{​​p> GL_PRIMITIVES_GENERATED也会打印所有网格面的数量。

1 个答案:

答案 0 :(得分:4)

您缺少的是您尝试使用的优化工作方式。

您正在谈论的具体优化是{{​​3}}。也就是说,如果要处理相同的顶点两次,则只处理一次并使用两次结果。

你不明白的是"同一个顶点"实际上是确定的。它不是由您的顶点着色器可以计算的任何东西决定的。为什么?好吧,缓存的重点是避免运行顶点着色器。如果顶点着色器用于确定该值是否已经缓存...您已经保存了任何内容,因为您必须重新计算以确定该值。

"相同的顶点"实际上是通过匹配顶点索引和顶点实例来确定的。顶点数组中的每个顶点都有一个与之关联的唯一索引。如果您使用相同的索引两次(当然只能使用post-caching of T&L),那么顶点着色器将接收相同的输入数据。因此,它将产生相同的输出数据。所以你可以使用缓存的输出数据。

实例ID也会发挥作用,因为在执行indexed rendering时,相同的顶点索引并不一定意味着与VS的输入相同。但即便如此,如果你获得相同的顶点索引相同的实例id,那么你将获得相同的VS输入,因此获得相同的VS输出。因此,在一个实例中,相同的顶点索引表示相同的值。

实例计数和顶点索引都是渲染过程的一部分。它们不是来自顶点着色器可以计算的任何东西。顶点着色器可以生成相同的位置,法线或其他任何内容,但实际的变换后缓存基于顶点索引和实例。

因此,如果您想要将某些顶点捕捉到相同的坐标以简化大型网格",则必须在渲染命令之前执行。如果你想做到这一点"在飞行中"在着色器中,您将需要某种instanced renderingcompute shader / geometry shader进程来计算新网格。然后你需要渲染这个新的网格。

您可以在几何着色器中放弃基元。但你仍然需要做T& L。另外,使用GS会减慢速度,所以我非常怀疑你通过这样做会获得很多性能。