在 OpenGL 的顶点着色器中获取元素 ID

Get element ID in vertex shader in OpenGL

我正在 OpenGL 中渲染一条由三角形组成的线。

现在我可以在以下地方使用它:

顶点缓冲区:{v0, v1, v2, v3}

索引缓冲区(三角条):{0, 1, 2, 3}

上图是传入顶点着色器的原始数据,下图是对 v1 和 v3(使用顶点属性)应用偏移量后的顶点着色器输出。

我的目标是在线上的每个点使用一个顶点并以其他方式生成偏移量。我正在查看 gl_VertexID,但我想要更像是元素 ID 的内容。这是我想要的设置:

顶点缓冲区:{v0, v2}

索引缓冲区(三角条):{0, 0, 1, 1}

并使用一个假想的 gl_ElementID % 2 来偏移每个其他顶点。

我试图避免使用几何着色器或其他顶点属性。有什么办法吗?我对完全不同的想法持开放态度。

不,那是不可能的,因为每个顶点只处理一次。因此,如果您使用索引缓冲区引用一个顶点 10 次,相应的顶点着色器仍然只执行一次。

这是通过 Post Transform Cache 在硬件中实现的。

In the absolute best case, you never have to process the same vertex more than once.

The test for whether a vertex is the same as a previous one is somewhat indirect. It would be impractical to test all of the user-defined attributes for inequality. So instead, a different means is used.

Two vertices are considered equal (within a single rendering command) if the vertex's index and instance count are the same (gl_VertexID​ and gl_InstanceID​ in the shader). Since vertices for non-indexed rendering are always increasing, it is not possible to use the post transform cache with non-indexed rendering.

If the vertex is in the post transform cache, then that vertex data is not necessarily even read from the input vertex arrays again. The process skips the read and vertex shader execution steps, and simply adds another copy of that vertex's post-transform data to the output stream.

为了解决您的问题,我会使用几何着色器,其中一条线(或线带)作为输入,三角形带作为输出。使用此设置,您可以摆脱索引缓冲区,因为它只在行上工作。

我能想到一种方法来避免几何着色器并仍然使用紧凑的表示:instanced rendering. Just draw many instances of one quad (as a triangle strip), and define the two positions as per-instance attributes via glVertexAttribDivisor()

请注意,您根本不需要具有 4 个顶点的 "template quad"。您只需要概念上的两个属性,一个用于起点,一个用于终点。 (如果您在 2D 中工作,当然可以将其融合为一个 vec4)。在每个顶点着色器调用中,您都可以访问这两个点,并可以根据该点和 gl_VertexID 的值(仅在 0 到 3 范围内)构造最终的顶点位置。这样,您就可以完全摆脱目标中每个线段两个点的顶点数组布局,并且仍然只需要一个绘图调用和一个顶点着色器。