Search code examples
opengl-esglslwebglshaderwebgl2

When does interpolation happen between the vertex and fragment shaders in this WebGL program?


Background

I'm looking at this example code from the WebGL2 library PicoGL.js.

It describes a single triangle (three vertices: (-0.5, -0.5), (0.5, -0.5), (0.0, 0.5)), each of which is assigned a color (red, green, blue) by the vertex shader:

    #version 300 es

    layout(location=0) in vec4 position;
    layout(location=1) in vec3 color;

    out vec3 vColor; 
    void main() {
        vColor = color;
        gl_Position = position;
    }

The vColor output is passed to the fragment shader:

    #version 300 es
    precision highp float;

    in vec3 vColor;

    out vec4 fragColor;
    void main() {
        fragColor = vec4(vColor, 1.0);
    }

and together they render the following image:

a multicoloured triangle

Question(s)

My understanding is that the vertex shader is called once per vertex, whereas the fragment shader is called once per pixel.

However, the fragment shader references the vColor variable, which is only assigned once per call to each vertex, but there are many more pixels than vertices!

The resulting image clearly shows a color gradient - why? Does WebGL automatically interpolate values of vColor for pixels in between vertices? If so, how is the interpolation done?


Solution

  • Yes, WebGL automatically interpolates between the values supplied to the 3 vertices.

    Copied from this site

    A linear interpolation from one value to another would be this formula

    result = (1 - t) * a + t * b
    

    Where t is a value from 0 to 1 representing some position between a and b. 0 at a and 1 at b.

    For varyings though WebGL uses this formula

    result = (1 - t) * a / aW + t * b / bW
             -----------------------------
                (1 - t) / aW + t / bW
    

    Where aW is the W that was set on gl_Position.w when the varying was as set to a and bW is the W that was set on gl_Position.w when the varying was set to b.

    The site linked above shows how that formula generates perspective correct texture mapping coordinates when interpolating varyings

    It also shows an animation of the varyings changing