Finally, we come to recursive ray tracing, and we will briefly explain how that is implemented. Let me review what happens for mirror reflections and refractions. Again, I have shown the virtual viewpoint of the camera. The camera, the ray from that hits the scene, in this case the plane, and you generate a reflected ray in the mirror direction. In this way, you can get the reflection and refraction of objects by recursively calling the intensity function for the new ray. Here is the basic idea of recursive ray tracing. And essentially, this is what has made ray tracing such a popular algorithm. You first trace the primary eye ray. You find the intersection. Then you trace secondary shadow rays to all the lights, and if the shadow rays return unblocked, you apply the illumination model. Otherwise, it's zero. It's the V term we saw in the previous segment. Finally, you trace the reflected ray, and the color of the reflected ray will be the initial color from this calculation plus the reflectivity times the color of the reflected ray. This is, of course, a recursive call, which gives the recursive ray tracing name. Here is the recursive shading model. So, the white parts of the shading model is what you saw earlier; it's really the green parts which I've added that are new. Which is this K_s * I_R and K_T * I_T. The highlighted terms are recursive, so the first term which is K_s * I_R, that is the recursive specularity of the mirror reflection. The last term is the mirror transmission, so if you hit a glass sphere, you reflect off it, but you also transmit into it. The latter term, or transmission, is not required in the homework assignment and is really extra. So what happens when you call I_R is that it's a recursive call, because you have to now evaluate the intensity again using the same formula. So you trace the secondary rays for more reflections and refractions and you include the contributions in the lighting model. So the lighting function, for example, GetColor, calls RayTrace recursively. Of course, recursion is one of the great inventions in computer science. It allows us to greatly simplify algorithms. It makes ray tracing so much simpler to implement in such a deep and elegant algorithm. However, recursion may go on forever. Consider a hall of mirrors, where reflected rays keep bouncing back and forth, and they go on forever. A simple solution is to set a maximum recursive depth, for example 5. And so, for each ray, you keep track of how many times it has gone through the recursion. Once it has gone through 5, it does not spawn new recursive rays. If you implement transmission, then you have to take Snell's Law of Refraction into account. Transmitted rays, similarly, have a certain recursion depth. Finally, I'd like to talk about a couple of very simple add-ons that you can do with your ray tracer for fun. Again, not required in the assignment. These are really extra. You can, of course, do a whole lot of other things. Ray tracing is something that's addictive. And you can really go overboard and make a very nice image synthesis system. But I just want to talk about two things. So, first we have considered only point and directional lights and in fact in OpenGL that's really all there is. But in a ray tracer it's easy to consider an area light source. Consider a light source like this. What do is we break into a grid. Here, I have shown one gridding of the area light. And in each of these grid cells you can essentially treat it as a point light source. So by shooting, let's say, 9 rays to various locations in this area light, you can replace the area light by 9 point lights. But one of the challenges if you do that is the shadows will have this jerkier quantized look where they suddenly jump from zero lights visible to 1 light visible to 4 lights visible, to 3 lights. So instead, what one does is jittering. Within each of these cells or strata, one randomly jitters the location of the ray. So at one pixel it might be here and the next pixel might be here and so on. This is something which is actually known as stratified sampling and is a very popular and useful concept. It can also be used for antialiased images, so if you render your sphere, and you really zoom into the pixel level, you see a stair step pattern. If you want to get rid of that, same idea: instead of shooting the ray to the center of the pixel, as in our solution, you shoot it randomly to a location in the pixel, again known as jittering. And that can be used to get rid of these jaggies and give us smoother planes. In any event, aerial light sources and soft shadows are something which is easy to do using a grid of n x n on the light source. The second thing that's easy to do is more complex reflectance models. If you study computer graphics further you will see that the Phong model is not the endpoint of things. You have the Torrance-Sparrow model. You have other complex reflectance models. And that's easy to do simply by updating the shading model. However, the basic Whitted ray tracing algorithm does have a limitation that we can only handle mirror reflection and refraction. There is a whole body of work that generalizes this to global illumination. Finally, I want to say that these segments that I have presented so far have introduced the very basics or very foundations of computer graphics. Beyond this, there are many exciting topics that can be considered, and I would encourage you to go to my website where I have links to the advanced computer graphics course at UC Berkeley, CS283, as well as some of the later segments in CS184 that cover more advanced topics in rendering, and CS283 goes into topics in modeling, topics in animation, topics in simulation. This is just the start of an incredible journey in computer graphics that I hope you have.