1 00:00:00,621 --> 00:00:03,043 - In this segment, we're going to go into detail 2 00:00:03,043 --> 00:00:06,007 about Gouraud and Phong shading. 3 00:00:06,007 --> 00:00:07,834 Let's first talk about Gouraud shading, 4 00:00:07,834 --> 00:00:10,418 which is the standard smooth shading. 5 00:00:10,418 --> 00:00:12,732 Note also that this is a lecture 6 00:00:12,732 --> 00:00:14,880 that actually talks about the operations 7 00:00:14,880 --> 00:00:17,502 that happen in rasterization. 8 00:00:17,502 --> 00:00:19,832 In a standard vertex or pixel shader, 9 00:00:19,832 --> 00:00:21,788 you would just give the colors 10 00:00:21,788 --> 00:00:24,103 for I_1, I_2, and I_3, 11 00:00:24,103 --> 00:00:25,395 and after you've done that, 12 00:00:25,395 --> 00:00:27,325 you would expect the rasterization hardware 13 00:00:27,325 --> 00:00:29,738 in OpenGL to do the interpolation. 14 00:00:29,738 --> 00:00:31,196 So you don't need to worry about 15 00:00:31,196 --> 00:00:33,807 the details of this for Gouraud shading. 16 00:00:33,807 --> 00:00:37,143 However, we are interested in learning, for this course, 17 00:00:37,143 --> 00:00:39,961 what actually goes on under the hood. 18 00:00:39,961 --> 00:00:42,844 So here we have three vertices, 19 00:00:42,844 --> 00:00:44,453 I_1, I_2, I_3, 20 00:00:44,453 --> 00:00:46,847 and those correspond to the colors here, 21 00:00:46,847 --> 00:00:49,389 so we assume I_1 is the color of vertex 1, 22 00:00:49,389 --> 00:00:50,785 I_2 is the color of vertex 2, 23 00:00:50,785 --> 00:00:52,805 I_3 is the color of vertex 3. 24 00:00:52,805 --> 00:00:55,669 Notice that the vertical extent 25 00:00:55,669 --> 00:00:58,336 goes from y_1, all the way to y_3. 26 00:00:59,292 --> 00:01:01,184 So we want to find first, the, 27 00:01:01,184 --> 00:01:02,367 to find the color of I_p, 28 00:01:02,367 --> 00:01:05,500 we first want to find the colors at I_a and I_b, 29 00:01:05,500 --> 00:01:07,902 and then we want to interpolate them. 30 00:01:07,902 --> 00:01:11,469 So let's first talk about the color at I_a. 31 00:01:11,469 --> 00:01:14,012 I_a lies between I_1 and I_2, 32 00:01:14,012 --> 00:01:15,591 so if you want to do the interpolation, 33 00:01:15,591 --> 00:01:18,349 we do it along the vertical direction. 34 00:01:18,349 --> 00:01:20,634 Look at the length of this region, 35 00:01:20,634 --> 00:01:22,641 and the length of this region. 36 00:01:22,641 --> 00:01:27,006 So the length of this region is y_1 minus y_s. 37 00:01:27,006 --> 00:01:28,256 The length here 38 00:01:29,125 --> 00:01:30,375 is y_s minus y_2. 39 00:01:32,226 --> 00:01:36,020 The total length, of course, is y_1 minus y_2. 40 00:01:36,020 --> 00:01:37,283 Now it's just a question 41 00:01:37,283 --> 00:01:40,480 of doing the standard interpolation formula. 42 00:01:40,480 --> 00:01:44,298 Which will mean that I_1, because it's further away from I_1, 43 00:01:44,298 --> 00:01:48,087 it will be multiplied by the smaller quantity. 44 00:01:48,087 --> 00:01:49,754 So this will get I_1, 45 00:01:51,208 --> 00:01:54,125 and this quantity will multiply I_2. 46 00:01:56,250 --> 00:01:58,114 Indeed, that's the formula here: 47 00:01:58,114 --> 00:01:59,864 I_1 times (y_s minus y_2), 48 00:02:01,161 --> 00:02:03,328 plus I_2 times (y_1 minus y_s). 49 00:02:04,969 --> 00:02:07,869 And divide the whole thing by the total length here, 50 00:02:07,869 --> 00:02:10,403 which is y_1 minus y_2. 51 00:02:10,403 --> 00:02:13,140 That's the formula for I_a. 52 00:02:13,140 --> 00:02:15,562 We can similarly get a formula for I_b, 53 00:02:15,562 --> 00:02:17,108 which will be equal to: 54 00:02:17,108 --> 00:02:19,108 I_1, times, in this case, 55 00:02:19,976 --> 00:02:20,976 (y_s minus y_3), 56 00:02:22,674 --> 00:02:24,757 and I_3 times (y_1 minus y_s), 57 00:02:25,953 --> 00:02:29,422 and now you normalize by y_1 minus y_3. 58 00:02:29,422 --> 00:02:32,284 Once you have the formulae for I_a and I_b, 59 00:02:32,284 --> 00:02:34,762 the question is, what do you get for I_p? 60 00:02:34,762 --> 00:02:36,381 And in order to consider that, 61 00:02:36,381 --> 00:02:39,188 one needs to consider the X-coordinates, 62 00:02:39,188 --> 00:02:42,833 because one is interpolating within a scan line. 63 00:02:42,833 --> 00:02:46,500 So we can consider this as being the x of a (x_a), 64 00:02:47,881 --> 00:02:51,298 and we can consider this as being x of b (x_b). 65 00:02:52,927 --> 00:02:55,677 Here, of course, you have x of p (x_p). 66 00:02:57,407 --> 00:03:00,572 So the interpolation idea is the same. 67 00:03:00,572 --> 00:03:04,654 You have this length, which is x_p minus x_a, 68 00:03:04,654 --> 00:03:08,424 and you have this length, which is x_b minus x_p. 69 00:03:08,424 --> 00:03:12,442 So I_a will be multiplied by (x_b minus x_p), 70 00:03:12,442 --> 00:03:16,165 and I_b will be multiplied by (x_p minus x_a). 71 00:03:16,165 --> 00:03:17,802 Indeed, this is what happens here. 72 00:03:17,802 --> 00:03:21,250 So you have I_a times (x_b minus x_p), 73 00:03:21,250 --> 00:03:25,468 plus I_b, which is multiplied by (x_p minus x_a). 74 00:03:25,468 --> 00:03:28,305 And again, you normalize by x_b minus x_a. 75 00:03:28,305 --> 00:03:31,725 So it's just interpolation first in the vertical direction, 76 00:03:31,725 --> 00:03:34,318 in order to get the locations 77 00:03:34,318 --> 00:03:37,470 for the end points of the scan line, 78 00:03:37,470 --> 00:03:41,139 and then interpolation along the scan line to get the, 79 00:03:41,139 --> 00:03:44,849 horizontally to get the final color of I_p. 80 00:03:44,849 --> 00:03:47,679 The actual implementation of this is much more efficient 81 00:03:47,679 --> 00:03:50,116 than the formulae will let you believe. 82 00:03:50,116 --> 00:03:51,897 For example, I can pre-compute 83 00:03:51,897 --> 00:03:54,306 the division by y_1 minus y_2, 84 00:03:54,306 --> 00:03:56,023 I can find the reciprocal of that, 85 00:03:56,023 --> 00:03:58,906 y_1 minus y_3, x_b minus x_a, 86 00:03:58,906 --> 00:03:59,746 and moreover, you see, 87 00:03:59,746 --> 00:04:02,090 as you go from one scan line to the next, 88 00:04:02,090 --> 00:04:05,283 the multiplicative factors, they reduce to addition. 89 00:04:05,283 --> 00:04:07,228 And therefore they are very efficient algorithms, 90 00:04:07,228 --> 00:04:08,528 that, in fact, don't involve 91 00:04:08,528 --> 00:04:10,329 multiplication or division at all, 92 00:04:10,329 --> 00:04:12,506 they just incrementally add quantities 93 00:04:12,506 --> 00:04:15,409 as you go from one scan line to the next. 94 00:04:15,409 --> 00:04:16,242 And this is a process 95 00:04:16,242 --> 00:04:18,916 which is generally known as scan conversion, 96 00:04:18,916 --> 00:04:21,479 but it also does the interpolation 97 00:04:21,479 --> 00:04:24,065 which is needed for Gouraud shading. 98 00:04:24,065 --> 00:04:26,224 Errors, we've already talked about those 99 00:04:26,224 --> 00:04:27,781 in the previous segment. 100 00:04:27,781 --> 00:04:30,665 So here is an extreme case, 101 00:04:30,665 --> 00:04:33,214 where I_1 and I_2 are zero, 102 00:04:33,214 --> 00:04:36,227 because either the light is pointing backwards, 103 00:04:36,227 --> 00:04:38,743 or the eye does not see the point. 104 00:04:38,743 --> 00:04:41,431 And now you have zeros in both cases, 105 00:04:41,431 --> 00:04:43,606 and you want to interpolate to make a highlight. 106 00:04:43,606 --> 00:04:45,241 Of course, that's not going to happen. 107 00:04:45,241 --> 00:04:46,769 If you have zero at the two vertices, 108 00:04:46,769 --> 00:04:49,112 the interpolation is also zero. 109 00:04:49,112 --> 00:04:52,520 And so Gouraud can have problems. 110 00:04:52,520 --> 00:04:54,687 Moreover, the way we implemented it, 111 00:04:54,687 --> 00:04:57,285 where we went vertically and then horizontally, 112 00:04:57,285 --> 00:05:00,148 means the shading is not rotationally-invariant. 113 00:05:00,148 --> 00:05:01,991 So if you were to rotate a point, 114 00:05:01,991 --> 00:05:04,516 you would actually see the shading change. 115 00:05:04,516 --> 00:05:07,528 For all of these reasons, Gouraud shading is useful 116 00:05:07,528 --> 00:05:10,658 only when you have relatively smooth shading effects, 117 00:05:10,658 --> 00:05:12,653 mostly for diffuse shading. 118 00:05:12,653 --> 00:05:14,972 But prior to the advent of fragment Shaders, 119 00:05:14,972 --> 00:05:16,897 you also needed to use Gouraud shading 120 00:05:16,897 --> 00:05:18,570 for specular highlights. 121 00:05:18,570 --> 00:05:21,489 And the way you handled that was by tessellating, 122 00:05:21,489 --> 00:05:24,149 or breaking the model into enough triangles, 123 00:05:24,149 --> 00:05:26,581 that, relative to the size of the triangles, 124 00:05:26,581 --> 00:05:28,796 the shading was still smooth. 125 00:05:28,796 --> 00:05:31,518 Next, we consider the Phong Illumnation Model, 126 00:05:31,518 --> 00:05:33,286 which is really the motivation also 127 00:05:33,286 --> 00:05:35,150 for the use of Phong shading, 128 00:05:35,150 --> 00:05:37,688 and the use of fragment shaders. 129 00:05:37,688 --> 00:05:40,723 And this corresponds to a specular or glossy material, 130 00:05:40,723 --> 00:05:42,628 where you have highlights. 131 00:05:42,628 --> 00:05:44,782 At the bottom I've just shown some renderings 132 00:05:44,782 --> 00:05:46,584 I made many years ago, 133 00:05:46,584 --> 00:05:49,386 where you've taken a lighting environment 134 00:05:49,386 --> 00:05:51,665 or a light probe that was acquired at Berkeley 135 00:05:51,665 --> 00:05:52,886 by Paul Debevec. 136 00:05:52,886 --> 00:05:55,571 It's in the Grace Cathedral in San Francisco. 137 00:05:55,571 --> 00:05:57,563 And I've rendered images 138 00:05:57,563 --> 00:06:00,364 with many different roughness settings, 139 00:06:00,364 --> 00:06:02,001 and you see from left to right, 140 00:06:02,001 --> 00:06:03,913 it starts off being a mirror, 141 00:06:03,913 --> 00:06:05,328 then it gets blurred out, 142 00:06:05,328 --> 00:06:06,630 and eventually in the right, 143 00:06:06,630 --> 00:06:09,267 it almost looks like a diffuse surface. 144 00:06:09,267 --> 00:06:11,346 And that, the amount of roughness, 145 00:06:11,346 --> 00:06:13,340 controls the width of the highlights, 146 00:06:13,340 --> 00:06:16,887 and your perception of how shiny the object is. 147 00:06:16,887 --> 00:06:19,343 Examples of specular or glossy materials 148 00:06:19,343 --> 00:06:23,260 are polished floors, glossy paint, whiteboards. 149 00:06:24,409 --> 00:06:26,952 Furthermore, highlights behave somewhat differently 150 00:06:26,952 --> 00:06:29,320 from plastics or dielectric materials 151 00:06:29,320 --> 00:06:30,954 as opposed to metals. 152 00:06:30,954 --> 00:06:32,787 So on plastics, the highlight 153 00:06:32,787 --> 00:06:34,126 is the color of the light source, 154 00:06:34,126 --> 00:06:36,081 not the body color of the object. 155 00:06:36,081 --> 00:06:37,589 And this is a very common thing, 156 00:06:37,589 --> 00:06:38,860 you could have a green ball, 157 00:06:38,860 --> 00:06:40,975 and you look at the highlight, it's still white, 158 00:06:40,975 --> 00:06:43,045 because the light source is white. 159 00:06:43,045 --> 00:06:44,343 Metals, on the other hand, 160 00:06:44,343 --> 00:06:46,514 the highlight depends on the surface color, 161 00:06:46,514 --> 00:06:48,650 and is modulated by the surface color. 162 00:06:48,650 --> 00:06:49,545 We don't have time 163 00:06:49,545 --> 00:06:52,921 to go into the physics of all of these effects; 164 00:06:52,921 --> 00:06:55,505 hopefully that's something you can look up, 165 00:06:55,505 --> 00:06:57,773 or we can cover in a future course. 166 00:06:57,773 --> 00:06:59,439 But these are basic properties 167 00:06:59,439 --> 00:07:02,174 of illumination and highlights, 168 00:07:02,174 --> 00:07:04,793 and it's also possible to regard them, really, 169 00:07:04,793 --> 00:07:07,117 as blurred reflections of the light source. 170 00:07:07,117 --> 00:07:08,605 If you look in the bottom panel, 171 00:07:08,605 --> 00:07:10,207 you can consider that the light source 172 00:07:10,207 --> 00:07:14,079 is just being blurred out as you go from left to right. 173 00:07:14,079 --> 00:07:16,997 So Phong illumination, coupled with Phong shading, 174 00:07:16,997 --> 00:07:19,460 is the appropriate way to make highlights. 175 00:07:19,460 --> 00:07:22,666 And again, it's worth noting the distinction between these. 176 00:07:22,666 --> 00:07:24,264 They're commonly used together, 177 00:07:24,264 --> 00:07:27,178 but technically, they're different aspects. 178 00:07:27,178 --> 00:07:29,273 The idea of Phong shading 179 00:07:29,273 --> 00:07:32,693 is simply that instead of interpolating the colors, 180 00:07:32,693 --> 00:07:36,614 what one actually does is interpolate the normals. 181 00:07:36,614 --> 00:07:38,971 So here we have the color was zero, 182 00:07:38,971 --> 00:07:42,191 but there's a correct normal in both of these locations. 183 00:07:42,191 --> 00:07:43,661 You interpolate the normal, 184 00:07:43,661 --> 00:07:46,015 and so you get the correct normal at the center, 185 00:07:46,015 --> 00:07:48,781 and therefore you can evaluate the illumination model 186 00:07:48,781 --> 00:07:50,389 and get a highlight. 187 00:07:50,389 --> 00:07:52,453 So the entire lighting calculation 188 00:07:52,453 --> 00:07:54,736 is performed for each pixel. 189 00:07:54,736 --> 00:07:57,651 In old style OpenGL, there was no Phong shading, 190 00:07:57,651 --> 00:07:59,393 it was just Gouraud shading, 191 00:07:59,393 --> 00:08:01,001 and therefore you would have to 192 00:08:01,001 --> 00:08:03,980 break this geometry up into enough triangles 193 00:08:03,980 --> 00:08:07,001 that it did actually compute the shading at each vertex. 194 00:08:07,001 --> 00:08:09,242 But in modern OpenGL and homework 2, 195 00:08:09,242 --> 00:08:11,028 you just write a fragment shader, 196 00:08:11,028 --> 00:08:14,879 and in this way, you can do perfect Phong shading. 197 00:08:14,879 --> 00:08:17,962 Let us now look at the vertex shader. 198 00:08:18,840 --> 00:08:20,566 Remember that this vertex shader 199 00:08:20,566 --> 00:08:24,022 comes from the mytest3 suite of programs. 200 00:08:24,022 --> 00:08:26,005 I encourage you to look at the code 201 00:08:26,005 --> 00:08:28,680 for these programs and the shaders, 202 00:08:28,680 --> 00:08:32,774 to get an idea of what you can do in OpenGL. 203 00:08:32,774 --> 00:08:35,524 First line says version 330 core, 204 00:08:36,390 --> 00:08:39,331 which just tells OpenGL that this shader 205 00:08:39,331 --> 00:08:40,914 is using GLSL 3.30, 206 00:08:41,857 --> 00:08:45,218 which is what we're using in our course. 207 00:08:45,218 --> 00:08:47,663 Let's now come to the per-vertex 208 00:08:47,663 --> 00:08:49,723 inputs to the shader. 209 00:08:49,723 --> 00:08:53,943 They're in location 0, location 1, and location 2. 210 00:08:53,943 --> 00:08:57,253 The layout command says which location are they in. 211 00:08:57,253 --> 00:08:59,566 in just says they're inputs, 212 00:08:59,566 --> 00:09:02,843 and vec3 says what kind of information is there. 213 00:09:02,843 --> 00:09:06,097 In this case, the position is the x, y and z coordinates, 214 00:09:06,097 --> 00:09:07,437 which is a three-vector. 215 00:09:07,437 --> 00:09:10,456 The normals, similarly, is the x, y, and z coordinates, 216 00:09:10,456 --> 00:09:12,768 it's a three-vector. 217 00:09:12,768 --> 00:09:16,850 The texture coordinates input are just two variables 218 00:09:16,850 --> 00:09:20,100 which are typically denoted as s and t. 219 00:09:20,940 --> 00:09:24,798 The outputs are the extra outputs from the vertex shader, 220 00:09:24,798 --> 00:09:27,221 which will be interpolated or rasterized, 221 00:09:27,221 --> 00:09:29,351 and sent to the fragment Shader. 222 00:09:29,351 --> 00:09:33,102 These correspond to myvertex for lighting calculations; 223 00:09:33,102 --> 00:09:35,799 mynormal, again, for the surface normals 224 00:09:35,799 --> 00:09:38,511 in the fragment shader for lighting calculations; 225 00:09:38,511 --> 00:09:40,483 and the texture coordinates, 226 00:09:40,483 --> 00:09:44,316 which will be provided to the fragment shader. 227 00:09:46,605 --> 00:09:49,167 Let's look in more detail at the shader. 228 00:09:49,167 --> 00:09:51,738 Again, we have the version 330 core. 229 00:09:51,738 --> 00:09:54,270 This was all the code we saw earlier. 230 00:09:54,270 --> 00:09:56,099 The uniform variables 231 00:09:56,099 --> 00:09:59,161 are variables that are the same for all vertices. 232 00:09:59,161 --> 00:10:01,520 In this case, they are the projection matrix 233 00:10:01,520 --> 00:10:04,889 and the modelview matrix. 234 00:10:04,889 --> 00:10:07,917 Both projection and modelview matrices 235 00:10:07,917 --> 00:10:10,108 are 4x4 matrices, 236 00:10:10,108 --> 00:10:13,866 which are specified with the command uniform mat4. 237 00:10:13,866 --> 00:10:15,788 istex simply says: 238 00:10:15,788 --> 00:10:18,804 are we doing texturing, or are we not? 239 00:10:18,804 --> 00:10:21,035 It's just a flag. 240 00:10:21,035 --> 00:10:21,868 The main routine 241 00:10:21,868 --> 00:10:25,623 is where the vertex shader is actually executed. 242 00:10:25,623 --> 00:10:27,832 gl_Position is a defined variable 243 00:10:27,832 --> 00:10:31,533 which sets the position within OpenGL 244 00:10:31,533 --> 00:10:33,267 for rasterization, 245 00:10:33,267 --> 00:10:36,891 which says where the vertex should go on the screen. 246 00:10:36,891 --> 00:10:38,211 As is conventional, 247 00:10:38,211 --> 00:10:39,735 the vertex location will be given 248 00:10:39,735 --> 00:10:42,007 by multiplying by the modelview matrix 249 00:10:42,007 --> 00:10:43,479 and the projection matrix; 250 00:10:43,479 --> 00:10:44,722 in fact, by the product 251 00:10:44,722 --> 00:10:47,652 of the projection and modelview matrices. 252 00:10:47,652 --> 00:10:49,577 Notice that we are now doing things 253 00:10:49,577 --> 00:10:51,236 in homogeneous coordinates, 254 00:10:51,236 --> 00:10:53,585 and therefore, we have to define a vec4, 255 00:10:53,585 --> 00:10:56,234 taking the x, y, z coordinates of the position, 256 00:10:56,234 --> 00:10:59,067 and the w-coordinate equal to 1. 257 00:11:00,448 --> 00:11:02,763 We also define the normal, 258 00:11:02,763 --> 00:11:05,603 which will be used in the fragment shader. 259 00:11:05,603 --> 00:11:08,612 This simply applies the normal transformation. 260 00:11:08,612 --> 00:11:10,589 Note that the normal transformation 261 00:11:10,589 --> 00:11:14,387 is given by the inverse transpose of the modelview matrix, 262 00:11:14,387 --> 00:11:17,788 which is why we are doing transpose inverse modelview, 263 00:11:17,788 --> 00:11:19,205 times the normal. 264 00:11:20,359 --> 00:11:24,977 We define the vertex location in eye coordinates, 265 00:11:24,977 --> 00:11:26,821 in the 3D world. 266 00:11:26,821 --> 00:11:28,526 This is different from gl_Position, 267 00:11:28,526 --> 00:11:30,738 which applies the projection matrix 268 00:11:30,738 --> 00:11:33,759 and tells you where it goes in the screen 269 00:11:33,759 --> 00:11:35,704 or in normalized device coordinates. 270 00:11:35,704 --> 00:11:39,104 However, we also need the value in eye coordinates 271 00:11:39,104 --> 00:11:40,459 in the 3D world, 272 00:11:40,459 --> 00:11:44,388 for later shading calculations in the Fragment Shader. 273 00:11:44,388 --> 00:11:47,613 That is done by multiplying the modelview matrix 274 00:11:47,613 --> 00:11:49,370 times the position, 275 00:11:49,370 --> 00:11:53,856 again, in homogeneous coordinates we made into vec4. 276 00:11:53,856 --> 00:11:57,226 Finally, we come to the texture coordinates. 277 00:11:57,226 --> 00:11:58,598 To avoid errors, 278 00:11:58,598 --> 00:12:02,073 I initially set the texture coordinate to (0,0), 279 00:12:02,073 --> 00:12:05,715 which is just the default value to prevent errors. 280 00:12:05,715 --> 00:12:10,176 In the next step, if texturing is turned on, 281 00:12:10,176 --> 00:12:12,299 then I have texture coordinates 282 00:12:12,299 --> 00:12:14,749 that were input to the vertex shader, 283 00:12:14,749 --> 00:12:18,049 and I just set texcoord equal to that. 284 00:12:18,049 --> 00:12:19,286 These texture coordinates 285 00:12:19,286 --> 00:12:22,249 will then be interpolated and rasterized, 286 00:12:22,249 --> 00:12:25,037 and they will be passed on to the fragment shader 287 00:12:25,037 --> 00:12:26,854 for texturing. 288 00:12:26,854 --> 00:12:28,640 The next thing we're going to talk about 289 00:12:28,640 --> 00:12:31,607 is the type of different lighting and materials. 290 00:12:31,607 --> 00:12:33,582 Lights: points and directional, 291 00:12:33,582 --> 00:12:37,223 and shading: ambient, diffuse, emissive, and specular.