## Homework 5, due Thursday, Oct 21

This is the second ray tracing assignment.

As we discussed in class, 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 using something like:

```   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/2); // COMPUTE RAY DIRECTION AT EACH PIXEL
w[1] = (double)(H/2 - j) / (W/2); //
w[2] = -focalLength;              // PLACE IMAGE PLANE AT z = -focalLength

rayTrace(v, w, rgb);              // RAY TRACE AT THIS PIXEL TO GET COLOR

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]))));
}
```

Also, as we discussed in class, you can add more logic at the end of your routine to trace a ray into the scene, to accomodate reflections:

1. Set t = infinity
2. Set object = null
3. Loop through all the spheres. For each spheren (with center cx,cy,cz and radius r):
1. Try to intersect the ray with spheren, to get tn;
2. If the ray intersects spheren at tn, and tn < t, then this is the nearest sphere, so:
1. Set t = tn
2. Set object = spheren
4. if object == null then
return background color

5. Compute surface point S = v + tw
6. Compute surface normal n = (S-[cx,cy,cz])/r
7. Compute reflection vector R = -2(wn)n + w
8. Create reflected ray with v = (SR) and w = R.
9. Recursively call this algorithm to compute the colorR seen by the reflected ray.
10. Return the product of colorR and the color of object.

You can also make a sphere out of materials other than chrome, by implementing a surface shading model. The shading model we discussed in class is the Phong model, described by:

Ambientcolor + SUMi ( LightColori * Diffusecolor * max(0,Lin) + LightColori * Specularcolor * (max(0,LiR)p )
where n is surface normal vector, p is the specular highlight power, R is the reflection direction vector, Li is the direction vector from the surface point to light source i, where i iterates over the light sources in the scene.

As I mentioned in class, there can be an odd effect from using (LiR) to compute the specular highlight, since it can return positive values even when the lightsource is below the surface horizon. You might want to try an alternate form, in which you compute the hightlight direction vector Hi, which is the reflection direction of the light source off the surface, and take the dot product between this direction and the direction back along the ray -w. This method is more computationally expensive, since you need to compute a separate Hi for each light source, but it produces better highlights. In this case the specular dot product term is:

(Hi • -w)         where:         Hi = 2(Lin)n - Li

For now you can just assume that the lights are all positioned essentially at infinity, so that all the rays of light from each light source will be parallel (like the Sun, for example). Practically, this means that you can just use a single direction vector for any one light source.

Note that each light source is described by: (i) its r,g,b color, and (ii) its x,y,z direction. So you need a total of six numbers to describe one light source.

As I said in class, if you're ambitious, you can also try to implement shadows, which really are not that hard to do with ray tracing. The trick is, when you're at a single surface point and looping over light sources, fire a ray from the surface point into the direction of each light source. If the ray hits any geomatry, then don't illuminate that surface point by that light source (ie: don't add in any Diffuse or Specular contributions for that light source).

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

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.

For extra credit:

Implement ray tracing to polyhedra. In class, we showed that you can do this as follows:

• Describe the polyhedron as an intersection of half-spaces, where each half-spac is a linear inequality (a,b,c,d), such that a point (x,y,z) is inside of the face when ax+by+cz+d <= 0. Note that the surface normal for a ray hitting this face is (a,b,c).

For example, the six linear inequalities for a unit cube are:

 a b c d x > -1 → -x-1 < 0 → -1 0 0 -1 x < +1 → +x-1 < 0 → +1 0 0 -1 y > -1 → -y-1 < 0 → 0 -1 0 -1 y < +1 → +y-1 < 0 → 0 +1 0 -1 z > -1 → -z-1 < 0 → 0 0 -1 -1 z < +1 → +z-1 < 0 → 0 0 +1 -1

• Ray trace to any planar face by substituting (vx+twx, vy+twy, vz+twz) for (x,y,z), and then solving for t = 0.

If the planar face is facing toward the camera (ie: if v is on the positive outside of the face), then t is a a point where the ray enters the polyhedron.

Conversely, if the planar face is facing away from the camera (ie: if v is on the negative inside of the face), then t is a a point where the ray exits the polyhedron.

• The place where the ray enters the polyhedron is the maximum among all the entering t values.

• The place where the ray exits the polyhedron is the minimum among all the exiting t values.

• If the entering t is less than the exiting t, then the ray has indeed struck the polyedron. Otherwise, the ray has missed the polyhedron.

• The normal at this surface point is given by the (a,b,c) coefficients of the plane at which the ray entered the polydron (ie: the entering plane that had the maximum value of t).