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.