 So triangle rasterization, how could we do this? Well, this is a fairly obvious solution, which unfortunately is quite expensive. What you would do is, well, we have three points in 3D space, and given three points in 3D space, you can figure out the planar equation, and for each pixel we can compute the equation of the 3D line that runs from the focal point and through that pixel center, and with these two equations we can solve for where x, y, and z satisfies both equations. And this is doable. It's just expensive because first you're finding the equation of the line for every single pixel. That's actually the cheaper part, but then finding the intersection that actually is a little expensive. More expensive at least than what we ideally would want to pay for each pixel. The other problem with this method is that actually what we really want to know about a pixel is not what is the corresponding 3D Cartesian coordinate. What we actually want to know is what is the corresponding barycentric coordinate? on the 3D triangle. So this method is already expensive, but the process of translating from the Cartesian coordinate to the barycentric equivalent is even more expensive. So this is not ideal. Now what would be really nice for efficiency's sake is, having computed the appropriate value for two or three of these pixels, we could then use linear interpolation within the view plane triangle to compute the rest. That'd be really nice. But because of how perspective works, because the lines of perspective fan out in a nonlinear fashion, there's not actually a linear correspondence between the points in our two-dimensional triangle in the view plane and the 3D triangle it corresponds to. It's just not a linear relationship. However, happily it turns out that there is a linear relationship between the so-called scaling factors as I call them and the points on the view plane. By scaling factor I mean the ratio of the focal length to the z, which is what we multiply the x's and y's of the 3D coordinates to get our corresponding points on the view plane. Now what this linear relationship means is that say on the view plane I have some point b of the view plane that's halfway between a of the view plane and c of the view plane. Well the corresponding point on the 3D triangle we'll call b, the scaling factor you multiply with b to get b of the view plane, that scaling factor is halfway between the scaling factors we multiply on a and c to get a of v and c of v. So on the view plane say I already know that for these two points on the view plane I know what the scaling factors corresponding to those points are in this case S of a and S of c and I want to find the scaling factor that applies to the point halfway in between them while it's just the average. I can do a linear interpolation and so for the halfway point it'd be S of a plus S of c divided by 2. So what this means then is if for a point on the view plane you know what the corresponding scalar factor for that point is we can work backwards to find the x and y 3D coordinates by dividing by the scaling factor. To go from the 3D plane to the view plane we multiply by S to go from the view plane to the 3D plane we divide by S. And thanks to the linear relationship between the scaling factors and the view plane we can compute the 3D coordinates corresponding to the pixel centers of our triangle in a quite more efficient way. For each of the three vertices of our 2D triangle we have the x and y on the view plane and we also have the scaling factor for that point. And we have three of these 3D coordinates so we can compute a planar equation and be clear. It wouldn't be a plane that when when graphed it wouldn't look like the plane of the original 3D triangle. It'll be different, but it would be something you can conceive of as a three-dimensional plane. But given this planar equation that we then can plug in x and v values and get out a corresponding S value. And so for the box encompassing our two-dimensional triangle on the view plane we find the view plane coordinates for every pixel center and we plug them into the planar equation to get the equivalent scaling factor for each of those pixels. And because we've said there's a linear relationship between the view plane coordinates and the scaling factors if I have two adjacent pixels I know what the scaling factors are. I get the delta between them and then I can just use that delta to fill in the rest of the pixels in the row or column. Let's say you have two pixels side by side left and right. You can just add that delta to each subsequent pixel to fill in the S values the scalar values in the rest of the row to the right and you could subtract to go in the other direction to go left. And the same principle holds for columns you find out the scaling values for a pixel and the one below it. You get the delta and then you can add that to get the S values for all the way down and then subtract to go all the way up. And so we're still paying the cost of finding the equation of a plane. There's a bit of work in finding the pixel centers on the grid of the view plane though that's fairly trivial. And then we have to plug in at least four pixel center view plane coordinates into our planar equation to get the scaling factors and then from there we we get the deltas between them and fill in the rest of the rows and columns. Like say we find the scaling factors for the top four pixels the two by two square in the top left. Well then you could fill in the left two columns and now you have two pixels in every row which you can find the deltas between to fill in the rest of every row. And through this process we now have the scaling factors of every pixel. We of course also know what the view plane coordinates are at those pixels. So for each pixel you take the x and y of the view plane divide both by the scaling factor of that pixel and we get the corresponding point on the 3D triangle. Now we're not quite done because as I explained we don't really actually care about the 3D Cartesian coordinates. What we really want are interpolations of the vertex attributes. What are vertex attributes? Well they can be whatever we want we can just associate with each vertex some piece of data that's going to have some meaning in how we want to render but the most common kinds of attributes that we attach to our vertices are RGB colors UV texture coordinates and normal vectors. Color values as we'll see in an early exercise can be used to determine what the colors of the pixel should be and normal vectors we'll see considerably later when we bring in lighting calculations you want to have the normals often influence how the lighting is performed and generally what we want to achieve is a smooth lighting effect on our geometry so that sort of disguises the angledness of our little triangles but that will come much later so let's just consider texture coordinates you want to paint a texture onto your triangles. Well the way this is done is that we have some two-dimensional texture image which is considered to have its own coordinate system of UV coordinates where U is the horizontal axis and V is the vertical axis with the origin usually in the bottom left as you see here in the picture and the idea is that say for a polygon let's say a triangle for each 3d vertex of our 3d triangle it has an associated attribute which is a UV coordinate a point on the UV texture such that the idea is that you want to imagine that portion of the UV texture painted on to the corresponding 3d triangle and these triangles don't have to be the same shape they don't have to be the same size what we want is for the texture to be squashed and stretched as appropriate to fit onto the 3d surface now for the points on the surface of our 3d triangle there is a linear mapping to the corresponding triangle on the texture for example when we render an edge of our 3d triangle the color we paint at the halfway point should match the color we see on the texture at the halfway point of the texture triangle's corresponding edge so again there's a linear relationship between the texture triangle and the 3d triangle but as we've already said because of the effective perspective there's not a linear relationship between our 3d triangle and the view plane triangle transitively then there's not a linear relationship between our view plane triangle and the texture triangle so when on our view plane for a pixel we want to figure out what the corresponding UV coordinate should be we can't just do a straight linear mapping we have to account for perspective and it turns out though for reasons I won't mathematically prove I'm vagrant on the proof myself but it can't be observed to be true that for any attribute whether we're talking about UV coordinates or RGB values or normal vectors for any attribute of our triangle vertices that scale linearly within the triangle then there's a linear relationship between our view plane and that attribute multiplied by the scaling factor so for a similar example as before we have some point b on the plane that's halfway between a and c on the plane and the corresponding texture chord u value of b on the 3d triangle that u value multiplied by the scaling factor of b that is actually halfway between the same thing computed for a and c if you took the scaling factor at a and its u coordinate value and the scaling factor at c and its u chord value multiply those pairs together and then average them you get the equivalent value of b's u times its scaling factor and so for a point on the view plane for a pixel we've computed what u times a scaling factor for that pixel should be and we also know what the scaling factor is then we can divide out the scaling factor to get u and the same logic for v so then to find the u chords for each pixel we find a planar equation for x and y of the view plane with u times the scaling factor instead of just a scaling factor like we did before we find the chords of the pixel centers and then we can use the planar equation to plug in x and y's for each pixel center to find the corresponding u times s for each pixel though again we can use the same delta trick to optimize we don't have to plug in x and y of every pixel center to get the u times s once we have just four then we can fill in the rest of the grid with cheaper addition operations and so now we have u times s for every pixel if we also have computed s for every pixel then we can get the us we take for a pixel its u times s divide by its s and get its u so in fact we can do this same process for all of the vertex attributes there are the g and the b of colors if our vertices have colors they use the v's if we have texture coordinates and if we have normal vectors then the x y z's of those vectors now this is beginning to sound a little costly because we'd have to compute all the scaling factors and then in that case if we had rgb colors uv chords and and normal vectors then you're talking about well that's eight attributes that we'd have to do this whole process for and that's getting a little expensive well it turns out there's another thing we can do to cut down this workload for a triangle we can describe points on its plane in terms of what are called barycentric coordinates the idea is that simply for each one of the vertices you have an associated weight that is somewhere in the range of zero to one and all of these weights when summed together always add up to one but then to find the x values say you take the x's of each vertices and multiply the respective weights and their sum gets you the x take the y's multiply them by the respective weights you get the y it's basically describing points within a triangle by how close they are proportionally to each of the three vertices so say if i have a barycentric coordinate which is 0.33 0.33 0.33 if they're all one third then we're talking about the logical center of the triangle if i have a barycentric coordinate of one zero zero then that means our point is one and the same as the vertex associated with the first weight and so forth so why do we care about barycentric coordinates well if we have a point within or on the edge of a triangle described in terms of its barycentric coordinates then for attributes associated with the vertices we can find the interpolation by simply plugging them into the formula we can simply multiply them by their respective weights and add them together just like we find the x y's and z's from the weights so instead of going through the whole process we just described finding the corresponding attribute at that pixel well generally be a little cheaper if we find the barycentric coordinate associated with each pixel of the view plane and use that barycentric coordinate to find the corresponding attribute value at that pixel now if you're just computing one vertex attribute it's cheaper just to directly compute it as we over described but as soon as you have generally three or four or more then there's a savings if instead we compute the barycentric coordinate and beyond that there's another really nice property of barycentric coordinates which is that for barycentric coordinates of points outside of the plane at least one of the weights if not two or three are going to be negative so if you compute the barycentric coordinates for a pixel we have a very simple test then to know whether it is inside the triangle or not if any of the values are negative then it's not inside the triangle so if we're going to compute the barycentric coordinate anyway to find the interpolated values of our vertex attributes then we can also use it to determine which pixels are inside the triangle without having to do a separate edge function calculation which is the other way of doing that okay now but how do we find the actual barycentric coordinates what's the cheapest way to do it well happily it turns out that just like there's a linear relationship between the view plane and any vertex attribute times it's associated scaling factor well for the barycentric coordinates time the scaling factor there is the same linear relationship and so given our view plane triangle we know what the corresponding barycentric coordinates are they're 1 0 0 for 1 vertex 0 1 1 for the second vertex and 0 0 1 for the third vertex that's always the case with any triangle those are the three vertices in barycentric coordinates and so we can find a planar equation expressing the relationship between the x's and y's of the view plane and the corresponding barycentric chord times corresponding scaling factor separately we find the scaling factors for each pixel and then by dividing out the scaling factor we can get just the barycentric chord for each pixel actually I should speak a little more carefully here of course we're basing the chord there are three different weights so you're finding three different planar equations and for every pixel you're finding three different barycentric weight time scaling factor values and so you do end up doing three divisions yes but generally particularly with many vertex attributes this still works out to be cheaper so the restoration process is actually the trickiest part of the whole thing and I did not give you an actual mathematical proof for why these linear relationships hold you can kind of just intuitively see them but I'm not giving you any formal proof and as you may have picked up there are many variations of how exactly to do rasterization what I'm describing is not exactly how it's done in any GPU hardware they all have variations they do a lot of tricks to optimize it as much as possible but what I've described is a workable process you could do your rasterization this way fortunately we don't really have to understand the details of this process because it is handled by the hardware for us this is a part of the graphics pipeline that is hardwired it is not programmable there are I think some advanced cases where it is useful to know exactly what's going on or have some details about what's going on but in vast majority of rendering we just take it as faith it's done for us when the hardware rasterizes a triangle what we're going to want in our pixel shader code is to have access to the vertex attributes of the triangle interpolated for this pixel and that is what the hardware will do for us it'll hand us the already interpolated values and interpolation as I described does account for perspective so say when we get the interpolated uv cords for a pixel they are perspective correct uv cords