6
\$\begingroup\$

I'm learning some OpenGL 3.2 way of doing things and I think it's quite great, I'm actually understanding more of shaders and non-fixed pipeline in 1 week rather than those 2 years I tried to learn OpenGL fixed pipeline functions. But here's my question:

From what I think I've understood the vertex shader is run for each vertexes in the VBO. But the fragments shader is run per each pixel (is that right?) which is a huge number compared to let's say 3 vertexes of a triangle.

Now it seems that in the vertex shader the out variables (like colors and stuff) are passed 1 to 1 to the fragment shader. But let's say that I pass to the fragment shader the position of the vertex in the vertex shader. How is all executed? What vertex (A, B or C of the hipothetical triangle) is passed per each fragment and why?

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

Because we're working with triangles all the information the vertex shader has can be interpolated along the surface of the triangle. A useful way of doing this is by using Barycentric coordinates.

OpenGL does this interpolation for us automatically, for example consider the following vertex shader:

#version 130

attribute vec4 position;        // vertex position from VBO
attribute vec2 uv;              // texture coordinates from VBO 

uniform vec3 camera;            // position of the camera   
uniform mat4 projection;        // camera projection matrix

smooth out vec2 texel;          // smoothed texture coordinate for fragment shader

void main()
{   

    gl_Position = projection * (position - vec4(camera.x, camera.y, camera.z, 0.0));
    texel = uv;
}

This is an extremely standard vertex shader. The vertex has a position which is transformed using the camera and projection matrices.

As you can see from the comment we also output a 'smoothed texture coordinate for the fragment shader'. Using the OpenGL keyword smooth we tell OpenGL to interpolate this variable over the surface of the triangle of which this is one vertex. Conversely there is also the flat keyword which doesn't do this.

Now in the frament shader we consume this data:

#version 130

uniform sampler2D diffuse;      // diffuse texture
smooth in vec2 texel;           // where we should sample the texture

out vec4 outputColor;
void main()
{
    outputColor = texture(diffuse, texel);
}

Et voila, we have our nicely textured triangle instead of just a triangle made up of the three colours made from whatever sample(texture,uv) would've been in each vertex.

Edit the following quote is directly take from the file teodron linked. I thought it would be a good idea to add this to the answer to make it more complete and hopefully answer Jeffrey's question in the comments.

The provoking vertex of a primitive is the vertex that determines the constant primary and secondary colors when flat shading is enabled.

In OpenGL, the provoking vertex for triangle, quad, line, and (trivially) point primitives is the last vertex used to assemble the primitive. The polygon primitive is an exception in OpenGL where the first vertex of a polygon primitive determines the color of the polygon, even if actually broken into triangles and/or quads.

\$\endgroup\$
4
  • \$\begingroup\$ Let's assume I do out vec3 VPosition; int main() { ... VPosition = position; } in the vertex shader. What would the value in vec4 VPosition; in the fragments shader for all of those fragments? \$\endgroup\$
    – Shoe
    Commented Dec 11, 2012 at 20:54
  • \$\begingroup\$ The uninterpolated value so position \$\endgroup\$
    – Roy T.
    Commented Dec 11, 2012 at 21:58
  • 3
    \$\begingroup\$ Of which vertex? A, B or C? \$\endgroup\$
    – Shoe
    Commented Dec 11, 2012 at 22:55
  • 2
    \$\begingroup\$ opengl.org/registry/specs/EXT/provoking_vertex.txt Related to your "which vertex" question.. \$\endgroup\$
    – teodron
    Commented Dec 12, 2012 at 9:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .