This will be an extremely simple assignment, just to set up the basic framework of ray tracing.
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 = [vx,vy,vz] into direction w = [wx,wy,wz].
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 create the ray at each pixel by:
v[0] = 0; v[1] = 0; // CAMERA EYEPOINT IS AT THE ORIGIN v[2] = 0; for (int i = 0 ; i < W ; i++) // LOOP OVER IMAGE COLUMNS for (int j = 0 ; j < H ; j++) { // LOOP OVER IMAGE ROWS 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 /* image[i][j] = rayTrace(v, w); // COMPUTE COLOR AT PIXEL BY RAY TRACING */ g.setColor(rayTrace(v,w)); g.fillRect(i,j,1,1); }
Given a ray v,w, and a collection of spheres, each of which is described by center coordinates and radius [cx,cy,cz,r], we can figure out which sphere the ray hits (if any) as follows:
For now, make all your spheres a single solid color, since you're only going to check to see whether you can get the above logic to work.
As we discussed in class, you can intersect ray v,w with sphere
(x-cx)2 + (y-cy)2 + (z-cz)2 = r2by substituting (vx + t wx) for x, (vy + t wy) for y, and (vz + t wz) for z in the sphere equation.
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:
( vx + t wx - cx ) 2 + ( vy + t wy - cy ) 2 + ( vz + t wz - cz ) 2 = r2Multiplying this out, we get:
(vx-cx) 2 + 2 (vx-cx)wx + t2 wx 2 + (vy-cy) 2 + 2 (vy-cy)wy + t2 wy 2 + (vz-cz) 2 + 2 (vz-cz)wz + t2 wz 2 = r2
This can be written as the quadratic equation At2 + Bt + C = 0, by rearranging terms:
A = wx 2 + wy 2 + wz 2 ,
B = 2 (vx-cx)wx + 2 (vy-cy)wy + 2 (vz-cz)wz ,
C = (vx-cx) 2 + (vy-cy) 2 + (vz-cz) 2 - r2
A more compact way of saying this using dot products is:
A = w w B = 2 (v-c) w C = (v-c) (v-c) - r2.
Your job is to come up with an interesting collection of spheres, each of which has a different color, and use the above code and equations to ray trace to them, to produce a picture.
Next week we'll work on the more advanced topics like shading, reflections and shadows.