Summit
Summit

Reputation: 2268

How the vertex shader is passing to the fragment shader

In the following vertex shader I am not able to understand what output does the lines 1 and 2 give out.

#version 450
out vec2 texcoord;
    
void main()
{
   texcoord    = vec2((gl_VertexID << 1) & 2, gl_VertexID & 2);  // Line 1
   gl_Position = vec4(texcoord * 2.0f - 1.0f, 0.0f, 1.0f);   // Line 2
}

Upvotes: 3

Views: 403

Answers (2)

Yun
Yun

Reputation: 3812

This is a method to define a full-screen quad using a single triangle.

A full-screen quad can be drawn as two triangles, but also as one large triangle which contains the quad. See here for more information.

In your example, the glDrawArrays function will be instructed to draw 3 vertices, causing the vertex shader to run 3 times for gl_VertexID 0, 1, and 2. This produces the following data:

gl_VertexID 0: texcoords(0.0F, 0.0F), gl_Position(-1.0F, -1.0F)
gl_VertexID 1: texcoords(2.0F, 0.0F), gl_Position( 3.0F, -1.0F)
gl_VertexID 2: texcoords(0.0F, 2.0F), gl_Position(-1.0F,  3.0F)

This defines a triangle in screenspace coordinates, going from the bottom left of the screen, then to the right ("beyond the screen"), and finally going to the top left ("beyond the screen"). The top-right corner of the quad sits on the hypotenuse of the triangle . The UV-coordinates are adjusted accordingly. The excess parts of the triangle will be clipped before rendering the quad's fragments.

The exact computations happen as follows:

We may assume this code is designed to only work for gl_VertexID 0, 1 and 2.

The bitwise AND in gl_VertexID & 2 clears all bits except for the second one, so the value 2 is kept at 2, any other value becomes 0. With a << 1 shift first, only gl_VertexID == 1 becomes 2 and any other value becomes 0.

For the gl_Position, the texcoords are mapped from the range [0, 2] to [-1, 3] to obtain the triangle vertex' positions.

Upvotes: 3

wohlstad
wohlstad

Reputation: 28084

Line 1 calculate texture coordinates (U,V in the range of 0..1 in the texture image). It fill's the texcoord variable, defined as an output from the shader in this line:

out vec2 texcoord;

Line 2 calculates the vertex position, and updates the predefined global variable gl_Position. This variable is then availavle as an outout from the shader.

More about opengl predefined global variables: Built-in Variable (GLSL).
More about gl_position: documentation.

Regarding the content of the output:
Looks like the U texture coordinate ((gl_VertexID << 1) & 2) is either 0 or 1 depending of the least significant bit in gl_VertexID, and the V texture coordinate (gl_VertexID & 2) is either 0 or 1 depending on the 2nd bit of gl_VertexID.
gl_Position x is either 1 if U is 1 and -1 otherwise. Similarly y is dependant on V.
I cannot say why it is required by the application to be that way.

Upvotes: 1

Related Questions