This will be the first of two ray tracing assignments.

As we discussed in class,
you can form a ray from a camera
into a scene for every pixel
of the image.
The ray goes from
**v** = [v_{x},v_{y},v_{z}]
into direction
**w** = [w_{x},w_{y},w_{z}].

We can just place the camera eyepoint at the origin,
so the first **v** will be [0,0,0].
Of course, when we start bouncing rays off of
objects to get reflections, shadows, etc.,
then **v** will take on all sorts of values.

You can calculate **w** for any pixel (i,j)
by placing the image into the scene
as sort of film plane, as we discussed
in class. You can put it along the z axis,
at z = -focalLength.
Remember, the smaller the value you choose
for focalLength, the more wide angle will be the view.
You will get reasonable looking pictures at focalLength values
of around 3.

If your image has W columns by H rows, then you can make an applet that extends class PixApplet.java. Your class should compute a color at every pixel by tracing a ray into the scene:

double rgb[] = {0,0,0}; double v[] = {0,0,0}; double w[] = {0,0,0}; .... public void setPix(int frame) { // SET PIXELS FOR THIS ANIMATION FRAME // (THIS OVERRIDES A METHOD IN PIXAPPLET CLASS) v[0] = 0; v[1] = 0; // CAMERA EYEPOINT IS AT THE ORIGIN v[2] = 0; int n = 0; for (int j = 0 ; j < H ; j++) // LOOP OVER IMAGE ROWS for (int i = 0 ; i < W ; i++) { // LOOP OVER IMAGE COLUMNS w[0] = (double)(i - W/2) / W; // COMPUTE RAY DIRECTION AT EACH PIXEL w[1] = (double)(H/2 - j) / W; // w[2] = -focalLength; // PLACE IMAGE PLANE AT z = -focalLength rayTrace(v, w, rgb); // RAY TRACE AT THIS PIXEL pix[n++] = pack(Math.max(0,Math.min(255,(int)(255 * rgb[0]))), Math.max(0,Math.min(255,(int)(255 * rgb[1]))), Math.max(0,Math.min(255,(int)(255 * rgb[2])))); }

Given a ray **v**,**w**,
and a collection of spheres, each of
which is described by center coordinates and radius
[c_{x},c_{y},c_{z},r],
we can figure out which sphere the ray hits
(if any) as follows:

- Set t = infinity
- Set
**object**= null - Loop through all the spheres. For each sphere
_{n}(with center c_{x},c_{y},c_{z}and radius r):- Try to intersect the ray with sphere
_{n}, to get t_{n}; - If the ray intersects sphere
_{n}at t_{n}, and t_{n}< t, then this is the nearest sphere, so:- Set t = t
_{n} - Set
**object**= sphere_{n}

- Set t = t

- Try to intersect the ray with sphere
- if
**object**== null then

return background color - Compute surface point
**S**=**v**+ t**w** - Compute surface normal
**n**= (**S**-[c_{x},c_{y},c_{z}])/r - Compute reflection vector
**R**= -2(**w**•**n**)**n**+**w** - Create reflected ray with
**v**= (**S**+ε**R**) and**w**=**R**. - Recursively call this algorithm to compute the
**color**_{R}seen by the reflected ray. - Return the product of
**color**_{R}and the color of**object**.

If you want to play it safe, you can start out by making a version of this applet that sets each of your spheres to a single solid color, just so you can check your basic ray tracing logic, and then add the reflection stuff after you get that first part working.

As we discussed in class, you can
intersect ray **v**,**w** with sphere

(x-cby substituting (v_{x})^{2}+ (y-c_{y})^{2}+ (z-c_{z})^{2}= r^{2}

When you do this you'll get some quadratic
equation in t.
There are two possibilities:
Either
*(i)*
this equation will have no real roots
(which means the ray missed the sphere entirely),
or else
*(ii)*
the equation will have two roots,
which means the ray has indeed hit the sphere.
In this case, the value of t that you want is the smaller of these two roots,
because that's where ray hits the *front* of the
sphere.

So let's do this substitution:

( vMultiplying this out, we get:_{x}+ t w_{x}- c_{x})^{2}+ ( v_{y}+ t w_{y}- c_{y})^{2}+ ( v_{z}+ t w_{z}- c_{z})^{2}= r^{2}

(v_{x}-c_{x})^{2}+ 2 (v_{x}-c_{x})w_{x}+ t^{2}w_{x}^{2}+ (v_{y}-c_{y})^{2}+ 2 (v_{y}-c_{y})w_{y}+ t^{2}w_{y}^{2}+ (v_{z}-c_{z})^{2}+ 2 (v_{z}-c_{z})w_{z}+ t^{2}w_{z}^{2}= r^{2}

This can be written as the quadratic equation At^{2} + Bt + C = 0, by rearranging terms:

A = w_{x}^{2}+ w_{y}^{2}+ w_{z}^{2},

B = 2 (v_{x}-c_{x})w_{x}+ 2 (v_{y}-c_{y})w_{y}+ 2 (v_{z}-c_{z})w_{z},

C = (v_{x}-c_{x})^{2}+ (v_{y}-c_{y})^{2}+ (v_{z}-c_{z})^{2}- r^{2}

A more compact way of saying this using dot products is:

A =w•wB = 2 (v-c) •wC = (v-c) • (v-c) - r^{2}.

Your job is to come up with an interesting collection of tinted reflecting spheres, and use the above code and equations to ray trace to them, to produce a picture.

If you're feeling ambitious you can try figuring out the equations for other shapes such as cylinders. You might also want to see if you can create a boolean combination (like intersection) of two or more spheres or other shapes.

You might find it useful to rotate the scene view direction
in response to mouse drags.
You can do this by transforming your original ray **v**,**w** by
a matrix, just as you did to change view direction in the previous assignment.

Next week we'll work on the more advanced topics like booleans and shading models (which we briefly discussed in this week's class), shadows, other shape primitives and ray perturbation.