顶点着色器如何将颜色信息传递给片段着色器? [英] How does vertex shader pass color information to fragment shader?

查看:162
本文介绍了顶点着色器如何将颜色信息传递给片段着色器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个简单的hello-world OpenGL程序中,该程序只需在窗口上绘制一个静态三角形, 当我将三角形的3个顶点设置为红色,绿色和蓝色时,三角形将充满渐变.

In a simple hello-world OpenGL program, which simply draws a static triangle on the window, when I set the 3 vertex of the triangle to red, green and blue color, the triangle is filled with gradient.

但是当我使用这样的着色器时:

But when I use shaders like this:

顶点着色器:

attribute vec4 aVertex;
attribute vec4 aColor;

varying vec4 vColor;

void main(void) {
    gl_Position = gl_ModelViewMatrix * gl_ProjectionMatrix * aVertex;
    vColor = aColor;
}

其中的属性aVertexaColor来自顶点缓冲区,通过调用glVertexAttribPointer传递.

where the attributes aVertex and aColor comes from a vertex buffer, passed through a call of glVertexAttribPointer.

片段着色器:

varying vec4 vColor;
void main(void) {
    gl_FragColor = vColor;
}

三角形仍然充满渐变,这是一个问题:

The triangle is still filled with gradient, and here comes the question:

如果按每个顶点计算顶点着色器,则应为vColor的每个实例分配一个顶点的颜色.顶点颜色应为红色,绿色或蓝色,如在顶点缓冲区中设置的那样.

If vertex-shader is calculated per vertex, then each instance of vColor should be assigned with the color of a vertex. And the vertex color should be either red, green, or blue, as set in the vertex buffer.

那么梯度从何而来呢?

So where did the gradient come from?

或者,换句话说,是什么时候发生在碎片着色器中的vColor是插值颜色而不是顶点颜色?

Or, in another word, when did it happen that in the frag-shader, the vColor turns out to be the interpolated color instead of the vertex's?

推荐答案

片段着色器中的可变"变量具有在顶点着色器阶段给定的值之间线性插值的结果(基于片段之间的相对位置)顶点.

"varying" variables in the fragment shader have the result of linearly interpolating between the values given at the vertex shader stage (based on the relative position of the fragment between the vertices).

也就是说,当光栅化器在一个像素处吐出一个片段时,其位置也相对于重心坐标中的三角形顶点给出.然后,将这些坐标用于对顶点着色器中的所有变化变量进行插值.在大多数情况下,这就是您想要的,并且如今不插值所获得的速度微不足道.

That is, when the rasterizer spits out a fragment at a pixel, its position is also given relative to the triangle vertices in barycentric coordinates. These coordinates are then used to interpolate all varying variables from the vertex shader. In most cases, this is what you want and the speed gained from not interpolating is pretty insignificant these days.

使用关键字"flat"将禁用插值,而是使用第一个顶点的值(我不是100%确定"flat"可以随着变化而工作,因为我已将输入/输出关键字与 GLSL的较新版本).

Using the keyword "flat" will disable interpolation and instead use the value of the first vertex (I'm not 100% sure "flat" works with varying as I've switched to using in/out keywords with the newer versions of GLSL).

另一方面,如果片段需要每个顶点中的一些值,我发现这特别有用.在这种情况下,我在几何着色器中使用flat out myVertexValue[3](例如,此处).

On a side note, I've found this particularly useful if the fragment needs some values from each of the vertices. In this case I use flat out myVertexValue[3] in the geometry shader (for example here).

这篇关于顶点着色器如何将颜色信息传递给片段着色器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆