在这个 WebGL 程序中,何时在顶点着色器和片段着色器之间进行插值?

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

背景

我在看this example code from the WebGL2 library PicoGL.js

它描述了一个三角形(三个顶点:(-0.5, -0.5), (0.5, -0.5), (0.0, 0.5)),顶点着色器为每个三角形分配了一种颜色(红色、绿色、蓝色):

    #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;
    }

vColor输出传递给片段着色器:

    #version 300 es
    precision highp float;

    in vec3 vColor;

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

他们一起渲染了下图:

问题

我的理解是顶点着色器每个顶点调用一次,而片段着色器每个像素调用一次。

然而,片段着色器引用了vColor变量,每次调用每个顶点只分配一次,但像素比顶点多得多!

生成的图像清楚地显示了颜色渐变 - 为什么? WebGL 会自动为顶点之间的像素插入 vColor 的值吗?如果是,插值是如何完成的?

khronos OpenGL wiki - Fragment Shader有答案。即:

Each fragment has a Window Space position, a few other values, and it contains all of the interpolated per-vertex output values from the last Vertex Processing stage.

(强调我的)

是的,WebGL 会自动在提供给 3 个顶点的值之间进行插值。

复制自 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.

上面链接的网站显示了该公式如何生成 perspective correct texture mapping coordinates when interpolating varyings

它也shows an animation of the varyings changing