How does vertex shader pass color information to fragment shader?

匿名 (未验证) 提交于 2019-12-03 02:50:02

问题:

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:

Vertex Shader:

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

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

Fragment Shader:

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

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

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?

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?

回答1:

"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.

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).

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).



回答2:

The gradient comes from the interpolation between vertex colors happening when the varying pass into fragment shader.If you don't want to interpolate use "flat" keyword at the begining of the varying . Your misunderstanding probably stems from the lack of knowledge on how vertex and fragment stages work.They work differently.Vertex shader is invoked per vertex while fragment -per-pixel.The interpolation happens by default as there is a need to cover fragments generated during rasterization stage on the area defined by the primitive assembly.And as I said you can disable interpolation by "flat".In such a case the color of the first vertex attribute will define the overall color of the shape.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!