Ray Tracing

If you have not done so already, please read the first part of this, Volume Ray Casting.

Basic Description

Ray tracing is a similar rendering method to volume ray casting. In ray tracing, the first three steps are the same, but the steps after the rays are calculated are different. Instead of sampling at regular intervals along the ray, you compute the the points where the ray intersects with the surfaces of the objects. This method can be used when the object data you are given is the equations of the shapes in the scene, instead of the set of 3D points used in volume ray casting.

A More Mathematical Explanation (continued)

The rest of the steps for ray tracing are:

4) Calculate the points the rays intersect with the objects
5) Find the visible intersection point on each ray
6) Calculate the shading for each visible intersection point
Figure 1: Ray-Sphere intersection

Step 4: Calculate the Points the Rays Intersect with the Objects

The way to calculate ray-object intersections is different depending on the type of object. I will show how to calculate the intersections with only two objects, spheres, and polygons. First we will do spheres. Spheres are the easiest to calculate, since you just need to plug the correct values into a formula. As you know, the equation for a ray is

$p(t) = e + td$

In step 3, we calculated d, the direction, and we are given e, the camera location. We also need the equation for a sphere.

$(p - c) . (p - c) - r^2 = 0$

p is any point on the sphere, r is the radius, and c is the center of the sphere. We combine these formulas and rearrange the terms to find t, which is the distance along the ray that the ray intersects with the sphere. This produces the following equation:

$t = (-d . (e-c) +/- sqrt((d . (e-c))^2 - (d . d) * ((e-c) . (e-c) - r^2))) / (d . d)$

Note: The periods indicate dot products.

This equation is rather large, so I will break it into chunks. First, calculate the part under the square root.

$temp = (d . (e-c))^2 - (d . d) * ((e-c) . (e-c) - r^2)$

If this value is negative, you are done with that sphere, because the ray did not intersect it. If it is positive, find the two t values.

$t = (-d . (e-c) + sqrt(temp)) / (d . d)$
$t = (-d . (e-c) - sqrt(temp)) / (d . d)$

These t values indicate the distances on the rays where they intersect with the spheres. These calculations must be done for all the spheres for each ray.

```Example

From the previous steps, we have the camera location, e, and the direction of the ray, d, and add a sphere with the given values.
$e = (3,2,1)$
$d = (0.995, 0.253, 0.357)$
Sphere:
$r = 1.5$
$c = (1,0,0)$

Calculate the value under the square root.
$temp = 2.853^2 - 1.181 * (9 - 1.5^2) = 0.168$

Since this is a positive value, continue with calculating the t values.
$t = (-2.853 + sqrt(0.168)) / 1.181 = -2.069$
$t = (-2.853 - sqrt(0.168)) / 1.181 = -2.763$

Plug the t values back into the ray equation to find the point.
$p(2.069) = (0.941, 1.477, 0.014)$
```

Figure 2: Ray-Polygon intersection

Now, suppose you have a scene with more than just spheres. You have a cube as well. You now need to calculate all ray-polygon intersections. The first step is to find the intersection of the ray with the plane the polygon resides in. The equation for this intersection is:

$t = ((p1 - e) . n) / (d . n)$

where n is the normal for the polygon, and p1 is a vertex on the polygon. Then plug the t value into the ray equation to get the intersection point. Once you have that point, project the polygon and the intersection point to a 2D XY plane. The easiest way to do this is to simply "throw out" one of the coordinates. Find the largest coordinate and remove it, and use the remaining two as the XY coordinates. Next, send out a vector from the point of intersection in the positive Y direction, and count the number of times the vector crosses an edge of the polygon. If the number is even, the ray doesn't intersect the polygon. If the number is odd, the ray does intersect the polygon, at the point of intersection previously calculated.

```Example

$e = (3,2,1)$
$d = (0.995, 0.253, 0.357)$
Polygon:
$n = (0,1,0)$
$p1 = (-5,0,-5)$
$p2 = (5,0,-5)$
$p3 = (5,0,5)$
$p4 = (-5,0,5)$

Calculate t.
$t = -2 / 0.253 = -7.905$

Calculate intersection point.
$p(-7.905) = (-4.865, 0.000, -1.822)$

Project to XY plane, removing Y.
$p1 = (-5,-5)$
$p2 = (5,-5)$
$p3 = (5,5)$
$p4 = (-5,5)$
$p(-7.905) = (-4.865,-1.822)$

Moving along the +Y axis, you cross one edge, (5,5) to (-5,5). So, the point is inside the polygon and the ray does intersect.
```

Step 5: Find the visible intersection point on each ray

This step is the easiest step of all. After all the intersection points with all the objects in the scene have been calculated, simply find the one that is closest to the camera on each ray. These are the only ones that are visible, so discard all the other ones.

Step 6: Calculate the shading for each visible intersection point

The last step is to apply shading to the pixel colors. There are many different ways to calculate shading, but let's just stick with a basic Lambertian diffuse shading. For each component of the color, RGB, the component's diffuse coefficient (amount of that color) is combined with the light intensity and the normal. Figure 3 demonstrates this calculation. The equation is:

$pixel color = color * kd * I * (n . L)$

Note: if (n . L) is less than zero, it is must be set to zero.

where kd is the material's diffuse coefficient, I is the intensity of the light, and L is the light ray. First, we must calculate L. It is found by just subtracting the intersection point from the light location that is being shaded.

$L = light - p$

After you have L, simply plug in the values into the equation and find the pixel value.

```Example

$p = (0.941, 1.477, 0.014) Light: [itex]light = (10,10,10)$
$I = 0.6$
Material:
$color = (255,100,5)$
$kd = 0.5$

Calculate L.
$L = (9.059, 8.523, 9.986)$

Calculate the new color.
$color = (255, 255, 18.291)$
```

Notice that the original color was orange, but the new color is more yellow, because it the light is washing out the color. If the intersection point was at a different location on the sphere, it may be a darker orange, or even close to black.

Once this shaded color value is calculated, it is stored as the color of the current pixel. When the color of all the pixels have been calculated, this data is output into an image file format of some type, so that it can be viewed.

Going Further

This is just a basic ray tracer, but it can be expanded on by adding reflection, refraction, shadows, and using more realistic shading, such as Blinn-Phong.