OpenGL退化GL_TRIANGLES共享相同的顶点

Posted

技术标签:

【中文标题】OpenGL退化GL_TRIANGLES共享相同的顶点【英文标题】:OpenGL degenerate GL_TRIANGLES sharing same vertices 【发布时间】:2015-12-22 19:06:15 【问题描述】:

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

在顶点着色器中,我想将一些顶点捕捉到相同的坐标,以即时简化大型网格。 结果,我预计性能会大幅提升,因为很多三角形都塌陷到同一点并且会退化。 但我没有获得任何 fps 增益。

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

是否有任何标志可以“激活”退化或我缺少什么?

glQuery of GL_PRIMITIVES_GENERATED 也总是打印所有网格面的数量。

【问题讨论】:

【参考方案1】:

您缺少的是您尝试使用的优化实际上是如何工作的。

您所说的特定优化是post-caching of T&L。也就是说,如果同一个顶点要被处理两次,您只需处理一次并使用两次结果。

你不明白的是“同一个顶点”实际上是如何确定的。它不是由您的顶点着色器可以计算的任何东西决定的。为什么?好吧,缓存的全部意义在于避免运行顶点着色器。如果使用顶点着色器来确定该值是否已被缓存...您没有保存任何内容,因为您必须重新计算它才能确定。

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

实例 id 也参与其中,因为在执行 instanced rendering 时,相同的顶点索引并不一定意味着对 VS 的相同输入。但即便如此,如果您获得相同的顶点索引相同的实例 id,那么您将获得相同的 VS 输入,因此也将获得相同的 VS 输出。所以在一个实例中,同一个顶点索引代表同一个值。

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

因此,如果您想“将一些顶点捕捉到相同的坐标以简化大型网格”,您必须在渲染命令之前执行此操作。如果您想在着色器中“即时”执行此操作,那么您将需要某种compute shader 或geometry shader/transform feedback 进程来计算新网格。然后你需要渲染这个新的网格。

您可以丢弃几何着色器中的图元。但是您仍然必须对其进行运输和运输。另外,使用 GS 会减慢速度,所以我非常怀疑这样做会不会提高性能。

【讨论】:

以上是关于OpenGL退化GL_TRIANGLES共享相同的顶点的主要内容,如果未能解决你的问题,请参考以下文章

Opengl ES 2.0 - glDrawElements(GL_TRIANGLES)的颜色不透明度问题

OpenGL:在 OpenGL-ES 之外,Triangle Strip 中的退化三角形是不是可以接受?

顶点着色器后的OpenGL三角形退化?

opengl

面向对象编程和OpenGL

openGL之API学习(一八零)POINTS LINES TRIANGLES QUADS 绘图顺序规则