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:
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:
Ambient_{color} + SUM_{i} ( LightColor_{i} * Diffuse_{color} * max(0,L_{i} • n) + LightColor_{i} * Specular_{color} * (max(0,L_{i} • R)^{p} )where n is surface normal vector, p is the specular highlight power, R is the reflection direction vector, L_{i} 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 (L_{i} • R) 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 H_{i}, 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 H_{i} for each light source, but it produces better highlights. In this case the specular dot product term is:
(H_{i} • -w) where: H_{i} = 2(L_{i}•n)n - L_{i}
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:
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
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.