Notes from the March 29 class (with homework assignment at end)

Ray tracing

Computing the inverse viewport

As we discussed in class, the viewport transformation for ray tracing goes from image space to object space, rather than the other way around.

When doing ray tracing, the first thing you need to do is compute this transformation, which you can do as follows.

Given a pixel (col,row) in the image, the ray through that pixel is computed as follows:

v = (0, 0, 0)

w = [ (col - 0.5*nCols) / nCols , (0.5*nRows - row) / nCols , -focalLength ]

normalize(w)

where normalize(vec) can be implemented as follows:

```          norm = sqrt(vec·vec)
for 0 <= i < 3
vec[i] /= norm
```
To render the image, we loop through all pixels:
For each pixel:
Compute point v and direction w that define the ray at this pixel
Loop through all spheres in the scene.
for each sphere, compute first root, if any
visible surface at this pixel (if any) is at sphere with smallest value of t

To intersect the ray with a single sphere:

Let P = [ wx t + vx , wy t + vy , wz t + vz ] (equation 1)

Points P on a sphere of radius r at center C is:

(P - C)2 - r2 = 0 (equation 2)

Plugging equation 1 into equation 2, we get:

(wx t + (vx - cx))2 + (wy t + (vy - cy))2 + (wz t + (vz - cz))2 - r2 = 0

Rearranging terms, we get:

(w·w) t2 + 2 w·(v-c) t + (v-c)·(v-c) - r2 = 0

Which gives coefficients for a quadratic equation in t:

A = w·w (which is 1.0), B = 2 w·(v-c), C = (v-c)·(v-c) - r2

t = -w·(v-c) ± sqrt ( (w·(v-c))2 - (v-c)·(v-c) + r2)

The ray hits the sphere iff the discriminant is non-negative.

The first of the two roots is where the ray enters the sphere.

Plug in this t into equation 1 to get the surface point S.

To compute the surface normal at S:
The surface normal for a sphere at center C and radius r is simply given by:

N = (S - C) / r

The reflection vector R:
To do both Phong shading and to create reflection rays, you will need to compute the reflection vector R.

Given the direction w along the ray, and the surface normal N, you can compute R as follows:

R = w - 2(N·w) N

The Phong algorithm is as follows:
Argb  +  i  Irgb (  Drgb (Li · N) + Srgb (Li · R)p  )
where we can model each light as a direction vector and an illuminance color:
Light = [ Lxyz , Irgb ]

That's a total of six numbers. The first three numbers Lxyz represent the direction vector toward the light source. For now you can assume that each light source is extremely far away (like light from the Sun), so that the direction vector remains the same no matter what the location of the surface point at which we are computing Phong shading.

The last three numbers Irgb represent the rgb illuminance of the light source (how much light the source produces, in each of red, green and blue).

Creating a Material object:
You should create an object class Material to store material data:
For now, Material will have 10 phong algorithm values:
•       Argb (ambient color, with 3 values)
•       Drgb (diffuse color, with 3 values)
•       Srgb (specular color, with 3 values)
•       p (specular power, with 1 value)
plus, in the case of ray tracing, the "mirror color" mcrgb, with 3 values:
If mcrgb is black (that is, [0,0,0]), there is no mirror reflection.
If mcrgb is white (that is, [1,1,1]), the surface acts like a perfect mirror.
If mcrgb is red (that is, [1,0,0]), the surface acts like a mirror tinted red.
Creating reflections:
If the mirror color for this surface is not black, continue tracing the ray path recursively by using the reflection vector R as the direction of the reflected ray, and by moving S by some small amount ε in that direction, to compute the origin of the reflected ray:

v' = S + ε R
w' = R

Return a mixture of Phong shading and the color from the reflected ray:

```      for (int i = 0 ; i < 3 ; i++)
color[i] = phong[i] * (1.0 - mc[i]) + reflection[i] * mc[i];
```
Homework assignment, due Thursday April 5, before class starts:
Implement a simple ray tracer, as per the above notes.

You should create an original scene consisting of spheres.