3
$\begingroup$

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?

$\endgroup$
4
  • 1
    $\begingroup$ The vertex shader usually sets ups any number of "varying" variables which are then passed to the fragment shader, it's these varying variables which get interpolated across the primitive. $\endgroup$
    – PaulHK
    Apr 17, 2020 at 9:52
  • $\begingroup$ See the function triangle for reference: github.com/ssloy/tinyrenderer/blob/master/our_gl.cpp $\endgroup$
    – lightxbulb
    Apr 17, 2020 at 10:17
  • $\begingroup$ @PaulHK so the interpolation uses variables from fragment shader? Then that means it does not happen inside rasterizer but rather in fragment shader? $\endgroup$
    – Anisa
    Apr 17, 2020 at 10:45
  • $\begingroup$ Some part of the interpolation is done outside of the fragment shader, be that interpolation of the actual vertex colours (or texture UVs etc). or it might just be barycentric coordinates which can be used to generate the interpolated values. $\endgroup$
    – Simon F
    Apr 17, 2020 at 17:28

1 Answer 1

2
$\begingroup$

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

$\endgroup$
6
  • $\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$
    – Anisa
    Apr 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, and tex_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 what a0 or a1 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.