Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does vertex shader pass color information to fragment shader?

Tags:

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?

like image 249
RnMss Avatar asked Aug 15 '13 13:08

RnMss


People also ask

How does a vertex shader pass data to a fragment shader?

A vertex shader receives its input data from a vertex attribute. But how does a fragment shader gets its data? Data is passed from shader to shader by using the in and out keywords. You create an output shader variable by using the out keyword.

What happens between vertex and fragment shader?

There are several kinds of shaders, but two are commonly used to create graphics on the web: Vertex Shaders and Fragment (Pixel) Shaders. Vertex Shaders transform shape positions into 3D drawing coordinates. Fragment Shaders compute the renderings of a shape's colors and other attributes.

How does a vertex shader work?

A vertex shader receives a single vertex from the vertex stream and generates a single vertex to the output vertex stream. There must be a 1:1 mapping from input vertices to output vertices. Vertex shaders typically perform transformations to post-projection space, for consumption by the Vertex Post-Processing stage.


2 Answers

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

like image 51
jozxyqk Avatar answered Oct 23 '22 20:10

jozxyqk


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.

like image 25
Michael IV Avatar answered Oct 23 '22 21:10

Michael IV