I am trying to program my own version of WEBGL graphics pipeline in python, however, I am confused as to where the color interpolation takes place in the pipeline. According to my research, it happens after the rasterizer has calculated the points covered by the primitive. Does that mean rasterizer has access to color attribute, if so, how is the color attribute passed to the rasterizer, as the inputs for rasterizer are vertices? Or is it happening in the fragment shader?
1 Answer
The rasterizer determines, which pixel is rendered depending on vertex positions that come out of the vertex shader. For each rasterized pixel, the rasterizer knows where it lies inside the triangle formed by its three positions. With the known position inside the triangle, the rasterizer can also interpolate the vertex values for each pixel. So it also calculates the interpolated color, in case your vertex shader passes a color down the pipeline. The interpolated value is then provided to the fragment shader. However, the fragment shader can still modify the color before it is finally rendered to the screen.
Does that mean rasterizer has access to color attribute
It has full access to everything that comes out of the vertex shader. A vertex shader must always have a position as output (gl_Position
). In some special cases also other outputs are required. However, if your initial vertices had a color, but the color is not passed down the pipeline by the vertex shader, the rasterizer won't produce an interpolated color. It only interpolates each variable/attribute, that comes out of the vertex shader.
how is the color attribute passed to the rasterizer, as the inputs for rasterizer are vertices?
You can define arbitrary outputs in your vertex shader. Even if the initially submitted vertex, did not have a color attribute, you can add a color output in the vertex shader. The data the rasterizer gets per vertex is just the vertex shader outputs. A vertex is a data point containing a position and optional additional values/attributes. So if a vertex has a color attribute, the rasterizer can see it, since it is part of the vertex.
Note that the vertices you pass into the vertex shader and the vertices that come out of it are not the same and might differ.
Or is it happening in the fragment shader?
No, the fragment shader receives already interpolated values as input. But it can decide to pass it directly, ignore it or modify it as you wish. If you just pass it through, you will see the interpolated vertex colors.
Further information can be found on this site
-
$\begingroup$ So i understand color is being passed down the graphics pipeline but how would the rasterizer identify the color variable as both vertex and color attributes are passed, especially if they are both defined as varying attributes? $\endgroup$– AnisaApr 28, 2020 at 12:33
-
$\begingroup$ This is what the linker does for you. If you have a vertex shader with the output variables
position
,color
, andtex_coord
, then your fragment shader needs the exact same variables as inputs (assuming geometry and tesselation shaders are not used). Otherwise, the linker would complain when you try to link the program. Since the linker takes care of the connection between the variables, the rasterizer does not need to know about the purpose or name of a variable he is interpolating. All he needs to know is where it comes from, which type it is and where the result must be written to. $\endgroup$– wychmaster ♦Apr 28, 2020 at 13:22 -
$\begingroup$ Additionally,
gl_Position
is a required output of a vertex shader. From that, the rasterizer knows the position of each vertex. That is all he needs to perform the rasterization. $\endgroup$– wychmaster ♦Apr 28, 2020 at 13:30 -
1$\begingroup$ The final color you see is determined by the fragment shader. It is whatever you write to
fragColor
(GLSL). The rasterizer just interpolates whatever you pass down the pipeline and does not know whata0
ora1
are supposed to be. In the fragment shader, you just get their interpolated values based on their position in the triangle. If you decide to discard those values, the interpolation was pointless, right. It's been a while since I have written my last shaders, but... $\endgroup$– wychmaster ♦Apr 28, 2020 at 14:14 -
1$\begingroup$ ... as far as I can remember if the compiler figures out, that a variable does not contribute to the output of a shader, it is optimized away. This will lead to a program linkage error since you have an output variable in the vertex shader but no corresponding input in the fragment shader. This should automatically prevent pointless interpolations. As I said, it has been a while. So I might be wrong here. $\endgroup$– wychmaster ♦Apr 28, 2020 at 14:18
triangle
for reference: github.com/ssloy/tinyrenderer/blob/master/our_gl.cpp $\endgroup$