Get item id in vertex shader in OpenGL

I draw a line consisting of triangles in OpenGL.

Now I work where:

Vertex buffer: {v0, v1, v2, v3}

Index buffer (triangle strip): {0, 1, 2, 3}

enter image description here

The top image is the raw data transferred to the vertex shader, and the bottom is the vertex shader output after applying the offset to v1 and v3 (using the vertex attribute).

My goal is to use one vertex at a point on the line and generate the offset in another way. I was looking at gl_VertexID, but I need something more like an item id. Here is my desired setup:

Vertex buffer: {v0, v2}

Index buffer (triangle strip): {0, 0, 1, 1}

and use the imaginary gl_ElementID % 2 to offset each other vertex.

I am trying to avoid using geometric shaders or additional vertex attributes. Is there any way to do this? I am open to completely different ideas.

+4
source share
2 answers

I can think of one way to avoid the geometric shader and still work with compact representation: instanced rendering . Just draw multiple instances of the same square (like a triangle strip) and define two positions as attributes of each instance using glVertexAttribDivisor () .

Note that you do not need a “square template” with 4 vertices. You just need conceptually two attributes: one for your starting point and one for your ending point. (If you are working in 2D, you can merge it into one vec4 , of course). In each vertex shader call, you will get access to both points and you can build the end position of the vertex based on this and the value gl_VertexID (which will only be in the range from 0 to 3). Thus, you can get away with exactly the same layout of vertices from two points to each segment of the line that you are aiming for, and you still need only one draw call and vertex shader.

+2
source

No, this is not possible because each vertex is processed only once. Therefore, if you reference a vertex 10 times with an index buffer, the corresponding vertex shader is still executed only once.

This is implemented on hardware with Post Transform Cache .

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

Checking whether the vertex is the same as the previous one is somewhat indirect. It would be impractical to test all user-defined attributes for inequality. Thus, instead, another remedy is used.

Two vertices are considered equal (within the same rendering command) if the vertex index and the number of instances are the same (gl_VertexID and gl_InstanceID in the shader). Since vertices for non-indexed rendering always increase, you cannot use the message convert cache with non-indexed rendering.

If the vertex is in the post-conversion cache, then this vertex data does not even need to be read from the input vertex arrays again. the process skips the steps for reading and the vertex shader and simply adds another copy of the post-thermal vertex transformation data to the stream output.

To solve your problem, I would use a geometric shader with a line (or linear strip) as the input signal and a triangular strip as the output. With this setting, you can get rid of the index buffer since it only works with lines.

+1
source

All Articles