Ray Tracing: Graphics for the masses
Summary:
We will skip most of the theory behind ray tracing, focusing instead on a general
overview of the technique from an implementation-oriented perspective. What is Ray
Tracing? Ray tracing is a technique for rendering three-dimensional graphics with very
complex light interactions. Ray traced image Some Terminology Before presenting the
full description of ray tracing, we should agree on some basic terminology. These objects
are part of a scene or world, so when we talk about "looking at the world" we're not
posing a philosophical challenge, but just referring to the ray tracer drawing the objects
from a given viewpoint. So the color of each point on real film is caused by a light ray
that passes through the aperture and hits the film, while in computer graphics each pixel
of the final image is caused by a simulated light ray that hits the view window on its path
towards the eye.
The name 'ray tracing' is a bit misleading because the natural assumption would be that
rays are traced starting at their point of origin, the light source, and towards their
destination, the eye. For all the rays that never reach the eye, the effort tracing them was
wasted. Lots of rays are wasted because they never reach the eye. Any given ray can
bounce around the room many times before reaching the eye. Its color is given by the
color of the light ray that passes through that point on the view window and reaches the
eye. We can just as well follow the ray backwards by starting at the eye and passing
through the point on its way out into the scene. The two rays will be identical, except for
their direction: if the original ray came directly from the light source, then the backwards
ray will go directly to the light source; if the original bounced off a table first, the
backwards ray will also bounce off the table. So the backwards method does the same
thing as the original method, except it doesn't waste any effort on rays that never reach
the eye. For each pixel on the view window, we define a ray that extends from the eye to
that point. The final color of the ray is given by the colors of the objects hit by the ray as
it travels through the scene. Just as in the light-source-to-eye method it might take a very
large number of bounces before the ray ever hits the eye, in backwards method it might
take many bounces before the ray ever hits the light. Since we need to establish some
limit on the number of bounces to follow the ray on, we make the following
approximation: every time a ray hits an object, we follow a single new ray from the point
of intersection directly towards the light source.
To handle reflection we also consider multiple bounces from objects, and to handle
refraction we consider what happens when a ray passes through a partially or fully
transparent object. If an object is reflective we simply trace a new reflected ray from the
point of intersection towards the direction of reflection. The reflected ray is the mirror
image of the original ray, pointing away from the surface. If the object is to some extent
transparent, then we also trace a refracted ray into the surface. If the materials on either
side of the surface have different indices of refraction, such as air on one side and water
on the other, then the refracted ray will be bent, like the image of a straw in a glass of
water. If the same medium exists on both sides of the surface then the refracted ray
travels in the same direction as the original ray and is not bent. The directions of the
reflected and refracted rays are given by the following formulas:
For a ray with direction V, and a surface with normal N, the reflected ray direction Rl is
given by c1 = -dot product( N, V ) Rl = V Note that since V, N, and Rl are vectors with x,
y, and z components, the arithmetic on them is performed per-component.
Now, each reflected and refracted ray can strike an object which spawns another two
rays, each of these may spawn another two, and so on. The root node of this tree is the
original ray from the eye, and each node in the tree is either a reflected or a refracted ray
from the ray above it.
For each point on the view window we call a function traceray(), passing it the ray from
the eye through the point. If a ray intersects an object, the object's intersection routine
returns the distance of the intersection point from the origin of the ray, the normal vector
at the point of intersection, and, if texture mapping is being used, a coordinate mapping
between the intersection point and the texture image. The distance to the intersection
point is needed because if a ray intersects more than one object, we choose the one with
the closest intersection point. Intersecting a Sphere for each type of object that the ray
tracer supports, you need a separate intersection routine. We will limit our ray tracer to
handling spheres only, since the intersection routine for a sphere is among the simplest.
The geometry of a ray R intersecting a sphere with center at O and radius r. Where, v2
b2 = c2 and d2 b2 = r2 and so d = sqrt( r2 - (c2 - v2 To determine whether an intersection
occurs, we compute the value of d. If d >= 0, then a valid intersection occurs. If the ray
does not intersect, then d will be less than zero. We step through each of the 640x400
points on the view window, defining a ray from the eye to that point. For each ray, we
calculate its intersection with all the objects in the scene. If the object is reflective, we
call the ray-tracing function again recursively, passing it the reflected ray direction.