在一个简单的hello-world OpenGL程序中,它只是在窗口上绘制一个静态三角形, 当我将三角形的3个顶点设置为红色,绿色和蓝色时,三角形用渐变填充。
但是当我使用这样的着色器时:
顶点着色器:
attribute vec4 aVertex;
attribute vec4 aColor;
varying vec4 vColor;
void main(void) {
gl_Position = gl_ModelViewMatrix * gl_ProjectionMatrix * aVertex;
vColor = aColor;
}
其中属性aVertex
和aColor
来自顶点缓冲区,通过调用glVertexAttribPointer
传递。
片段着色器:
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
三角形仍然充满了渐变,问题出现了:
如果每个顶点计算顶点着色器,则应为vColor
的每个实例分配顶点的颜色。并且顶点颜色应该是红色,绿色或蓝色,如顶点缓冲区中设置的那样。
渐变来自哪里?
或者,换句话说,在片段着色器中发生的时候,vColor
原来是插值颜色而不是顶点?
答案 0 :(得分:16)
也就是说,当光栅化器在像素处吐出片段时,其位置也相对于重心坐标中的三角形顶点给出。然后使用这些坐标来插入来自顶点着色器的所有变化变量。在大多数情况下,这就是你想要的,而非插值所获得的速度这些天来是非常微不足道的。
使用关键字“flat”将禁用插值,而是使用第一个顶点的值(我不是100%确定“flat”可以使用,因为我已切换到使用输入/输出关键字{{ 3}})。
另外,如果片段需要来自每个顶点的一些值,我发现这特别有用。在这种情况下,我在几何着色器(newer versions of GLSL)中使用flat out myVertexValue[3]
。
答案 1 :(得分:1)
渐变来自于变化传递到fragment着色器时发生的顶点颜色之间的插值。如果您不想在变化开始时插入使用“flat”关键字。 你的误解可能源于缺乏关于顶点和片段阶段如何工作的知识。它们的工作方式不同。每个顶点调用Vertex着色器而片段为-per-pixel。默认情况下插值是因为需要覆盖光栅化过程中生成的片段在原始程序集定义的区域上的阶段。正如我所说,你可以通过“平面”禁用插值。在这种情况下,第一个顶点属性的颜色将定义形状的整体颜色。