In this lecture we are going to study shading in OpenGL which is critical in order to do homework 2 and gets you excited about the way in which you can actually light and shade objects in a scene. In particular this lecture deals with lighting and will briefly explain the shaders that we used for the mytest3 program that you compiled for homework 0. We'll do this before explaining the full code base for mytest3, so that you have all of the material you need to get started on homework 2. Furthermore, we will explain all of this with reference to the source code; there is of course an interesting question about how to in a correct and physically based way, how do you do shading. We will not get into that in this lecture. It's an interesting topic that we hope to cover in a future course. As far as this lecture is concerned it will deal with the nuts and bolts of how do you create a nice smooth shaded scene. I'm showing you the demo for homework 2 here. This is the solution. The idea is that you read a text file that specifies all of the geometry here. And then your program will display the scene with the correct shading. Notice that I still have the same functionality I had in homework 1. Which is that I can move about the scene. And the shading, you notice the highlight here that changes as I move the scene to different locations. Notice that you have highlights, both you have the red and the blue highlight on the teapot. You have highlights on the spheres. This lecture and homework 2 will tell you how to basically create a nice scene, like what we just saw. Let me also go back to the demo for mytest3 and as I bring up the demo in a moment pay attention to these different aspects. You'll notice that the teapot has lighting on it. It has the red and blue highlights that you can see. Also notice that you have diffuse shadings. So where you don't see the red and blue highlights the teapot is still lit and it's still shaded. You'll notice that the floor has this wood texture in it. And you'll further notice that all of the shading is not pasted onto the object. It actually updates as you move around. So here is my scene, and I can get the teapot to animate. So, in this case, the teapot is animating somewhat slowly, so you can see the motion. And here you notice that you have the blue and the red highlights, and as the teapot is moving those highlights are changing slowly; their locations are changing. You notice the texture on the wooden floor, and you also notice that where you don't have highlights on the teapot, you have this general diffuse shading. Why do we care about lighting? In the previous lecture on OpenGL, we just set up a basic scene with 2 quads. Of course you won't be very happy with that if you just have a quad in the scene. And lighting is important as shown here. So if you look at the sphere on the left, you'll see that it's rendered with flat shading, and there you can see the polygonal facets. But, it still looks somewhat interesting because you have that highlight on this sphere. If we were to just paint it in a constant color it would look like a flat disc made of paint and indeed the image on the screen is just a circle. So it's not any different from a disc. So in fact, by putting in the shading, the diffuse shading, also the highlights, it really gives the appearance of shape perception. If you've taken a computer vision course, one of the key cues by which we perceive shape is shading. And in fact there's a rich area in computer vision known as shape from shading. So this accurate lighting and shading is really important to convey the shape of the object. Furthermore, it then looks like an image that you can imagine in the real world. The way shading is done is also important. In flat shading, the entire face has a single color from 1 vertex. And so you can think about this as being a flat plane, that just gets lit by the color at the left-most vertex, for example. Also, if you have a surface normal, that normal is assumed to be the same across the face. And for this reason, you do see the polygon or faceted appearance on the left. Whereas on the right, you are actually using the same geometry, but in fact you, it enables smooth shading. So this is something that was invented by Henri Gouraud, at the University of Utah. And what he does is a simple interpolation of shading across the vertices. Furthermore, you can interpolate the normal across the vertices to get specular shading to work out. We'll study all of these in subsequent segments. Before we go further, all of you are used to looking at color images. And so we have to say something about color. Now color is a fascinating topic and it's something we could spend an entire course on. But here I'm going to give you a very brief one slide primer on color. As humans, we are largely sensitive to these three primary colors: red, green and blue. Of course in practice we have a range of sensitivities across the visible spectrum but, we have standardized in computer displays for these three primary colors and one of the common illustrations you see in books is a color cube where you place red, green and blue at the vertices of the cube and then you can combine colors in various ways, and this can be drawn in fact as a Venn diagram. So let me draw this here, so you can imagine that this is equal to red, and then you have the green color here, and I draw the blue color here. Okay? So this area, where red and green meet, this area here, is what will be yellow. Whereas this area, where red and blue meet here will be magenta, and where green and blue meet here will be what's known as cyan. And then the interesting thing is what happens when all of them combine here, and that is white. So red plus green plus blue is equal to white. The intersections of red and green is yellow, blue and green is cyan, blue and red is magenta. These are known as the secondary colors. And red plus green plus blue is equal to white. For some of you who've been interested in paints, or even like what you get on a printer, these relations may seem a bit strange. That's because on a computer display you do colors in an additive fashion. So you add colors. So that means when you say red plus green you are adding red and green color. Whereas in paints or even in printers it's actually subtractive model where you have a certain base color and by then adding another color you actually do a subtraction and those color spaces are different. Now, each color channel, red green and blue is treated separately. That is the common assumption. Of course, in reality you want a full spectral color distribution. Within computer graphics or digital computers we just deal with 3 primaries. In OpenGL, one very often uses an RGBA mode, where RGB is fairly clear, and you typically use 8 bits per color channel. "A" stands for alpha or transparency. We won't get into it much here, but you can imagine that you want to blend one object or the other. So totally, this corresponds to 32 bits or 4 bytes, and in the frame buffer you will typically need 4 bytes for each pixel in the frame buffer. In OpenGL, colors are normalized from the range from 0 to 1. But of course, if you representing them with 8 bits, they have to range from 0 to 255 in terms of pixel intensities. And if you look at the image and you inspect it in some kind of program, typically you'll get a value from 0 to 255. But OpenGL tries to abstract that for the most part, considering colors normalized from 0 to 1. They do clamp to that range, so if you get a color greater than 1, it will clamp to 1, and if you get the color less than 0 it will clamp to 0, and only in the final stage are those appropriately quantized and displayed in the image. Let me give you a brief outline of what the rest of this lecture is about. First we'll talk about Gouraud and Phong shading. In the context of homework 2 or in the context of the OpenGL pipeline, those largely correspond to vertex of fragment shading. And then we'll talk about the types of lighting materials and shading. So we'll talk about point and directional light sources. We'll talk about ambient, diffuse, emissive and specular shading. We'll describe the fragment shader that was used in mytest3. And you will need a somewhat generalized version of this for homework 2, and we'll discuss the source code in the display routine. Let me first say a few words about vertex versus fragment shaders. You can use either of these for lighting and they really correspond to what you think about. The vertex shader operates on vertices and the colors from that are interpolated across the pixels or across the fragments. On the other hand, the fragment shader receives some variables from the vertex shader. So, you may for example have normals at the vertex shader that are interpolated and passed to the fragment shader. And the fragment shader then at each fragment or each pixel does the lighting computation. In traditional OpenGL, before the advent of shaders, all of lighting was handled on a per-vertex basis. So essentially using a fixed vertex shader, because it's cheaper. If you have fewer vertices than fragments then typically you want to design your scenes so you have a polygon occupy several pixels. Then it is just cheaper to compute the expensive lighting computation of the vertices and then use the rasterization hardware to interpolate it. So that is the basic idea of Gouraud or smooth shading, and we saw an example in mytest1 in the previous lecture. Flat shading is of course even simpler, where one just uses the color at a single vertex and does no interpolation at all, and that leads to the faceted appearance we saw earlier. However, in today's hardware first it's a lot cheaper to write fragment shaders. The performance penalty is not that large. And second, many times the geometry is significantly dense that the number of vertices is proportional to the number of pixels. And this allows us to do more interesting lighting calculations. So for example, highlights very often don't really work well with a vertex shader. You need to tessellate or add enough triangles to your scene so that you actually can represent fine highlights. But they're easy to do in pixel shaders or fragment shaders. So, today, it's very often just more convenient to write the lighting calculation in a fragment shader. That's what's done in mytest3, that's what you should do in homework 2. In this case, what you will end up doing is that you will get the normals at the vertices. Maybe other information, but the most useful thing is the normals. You will interpolate to get a normal at the particular pixel, and then you will shade it using the shading formula. This is a technique that is known as Phong shading. I will just highlight that. And it's named for Bui Tuong Phong who again invented this in the University of Utah, where a lot of the early work in graphics is done. The idea, let me just briefly describe it. You have a curved surface like this and you have a vertex here and you have a vertex here. You have a normal here and you have a normal here. You interpolate these and you get a normal here. And this is what the normal you use for shading. On the other hand, if you had a highlight here it would show up properly. On the other hand if you just interpolated the shading of the vertices you may say there's no highlight here. There's no highlight here. So there's no highlight here. Phong shading is different from Phong illumination. Phong illumination is the formula that goes in the fragment shader in order to produce highlights. Phong shading is an approach whereby you interpolate normals, and then you apply the formula to the normals. So it's possible to use Phong shading with a different illumination model such as the Torrance-Sparrow which is one of the BRDF or the reflection models. There are others; we'll talk about the Blinn-Phong model. But, it was originally proposed by Phong so that he could combine the Phong illumination model, but in order to get highlights, you also needed Phong shading, and of course it's more accurate. We'll talk about both of these later, in later segments, and we'll discuss the whole range of shading options that one typically uses in OpenGL.