In this assignment you will be asked to implement a ray casting algorithm and render 3 scenes. Unlike the earlier assignments, the guidelines for this assignment will be more general and there will be more room for interpretation. So long as you pay attention to the specific requirements elaborated below, and correctly implement the critical aspects of the ray tracer, you should satisfy the requirements of this assignment. To summarize, you will need to implement multiple light sources interacting with multiple 3-D object models. Both diffuse and specular reflection will have to be present in your rendered scenes.
For this assignment, you're going to need polygonal models as well as spheres. Further, in order to render a sphere using a ray tracing algorithm it is profoundly simpler to represent the sphere in terms of a center position and radius. Messing around with tessellation's involving triangles creates tremendous amounts of extra work while at the same time producing an inferior result. This means, unfortunately, your best option is to extend slightly the reduced subset of the .obj file spec.
A quick scan of the .obj file specification suggests both that there is no provision for an elliptical solid and also there is no use of an "e" tag. Here's a suggestion that you are strongly encouraged to follow. Add to what you already have in your .obj file handling capability the ability to process a new ellipticla solid specification:
For a sphere, simply give the same value for each dimension.
In this assignment, you will also need material properties. Very briefly in lecture you were shown how this is handled by SketchUp Pro. Specifically, a reference to a materials file is added to the top of the .obj file. The material also named and then stated as the material to use before faces are defined. This is the approach you should take in this assignment. Note that the contents of the material filed at this stage is relatively simple. There is a line declaring the name of the new material followed by 3 lines that set out the constants for ambient, diffuse, and specular illumination in the red, green, and blue channels.
For this assignment you will have to add the ability to specify multiple light sources in your command file. This will be done using the following syntax:
The light source position is specified in homogeneous coordinates because it is allowable for the w coordinate to be zero, indicating a light source that is infinitely far away in the direction of x, y, z. In this case, the vector from a point P to the light source is simply and always in the direction (x, y, z). Remember to normalize this vector before using it in illumination calculations.
Note that much like vertices, the light sources are not named. Instead, simply follow the convention within your code that the first defined light is light source 1, etc.
The actual command to specify a camera will use exactly the syntax introduced in our previous assignment. However, there is going to be a major change to how the final step of mapping to pixels is carried out. This change will implement a canonical viewport going from (-1, -1) to (1, 1). Therefore, realize that the specification of the focal length will now have to be interpreted in terms of a camera geometry where the image plane is of size 2 x 2. Further, the final step of interpreting the canonical viewport in terms of actual pixels will be handled by the command which will invoke the actual ray casting action. That command will be explained shortly. But first, mostly as review, here is the syntax for specifying a camera:
To reiterate, and for the sake of clarity, in this assignment the focal length d is with respect to a bounded image plane centered about the optical axis and 2 units in length both in the vertical and horizontal directions. This means that a focal length specification of 2 units places the focal point behind the image plane by exactly as much distance as the image plane itself is wide.
In the previous assignment there was a command to generate a wireframe rendering. In this assignment, there will be a new command that triggers ray casting and results in a ray cast image being saved to a file. Here is the command:
Specifying the pixel resolution in this manner will turn out to be convenient insomuch as you can test your code using low-resolution specifications such as 32 32 and when you're content that the results seem reasonable simply changing this to 256 256 will not change the viewing geometry but will of course dramatically increase the pixel sampling density resulting in a higher resolution image. The last argument will not be used in this assignment, it represents the depth of recursion for the ray tracing. In this assignment, you will not be asked to perform recursive ray tracing.
There is a lot going on within this assignment. Here's a brief summary of what you are being asked to implement. You're being asked to create the code required to intersect a ray emanating from a pixel with every surface in the scene model you have loaded from a .obj file. You are being asked to determine the nearest intersection and compute the illumination for that point on that particular surface. This means you will have to look up the material properties associated with that surface. It also means you will have to determine the surface normal. Here we will introduce one simplification. The surface normal will always be the true surface normal defined by either the planar polygonal surface patch or the associated point on the elliptical solid. As we will shortly discuss in lecture, determining the normal on the elliptical solid is very easy.
When computing the illumination you are being asked to compute all 3 forms: ambient, diffuse, and specular. As we discussed in lecture, the ambient term will most likely be turned off by specifying all zero coefficients for the material at some point, but it is handy when initially debugging your code. You are being asked to implement shadows. What this means is that before you can compute the diffuse and specular illumination for a particular light source, you must shoot one additional ray through your scene model originating at the point on the surface being eliminated and terminating at the light source. The rule for whether the light source is visible is then simple, if you intersect any other surface on the way to the light source, then stopped and do not illuminate this particular point with light from this particular light source.
Since there is already a lot going on assignment, you will not be asked to carry out recursive ray tracing. Hence, once you correctly computing illumination for the point of intersection with the closest surface you may write that into the pixel and be done (with that pixel).
You will create the .obj, associated material file and command file to render three sucessively more complex scenes. Please name these using the convention "scene01.obj", "scene01.mtl", etc. This should result in your turning in nine files along with your code, three for each scene.
Scene 1:
In this scene place a sphere of radius 2 at the origin of the scene. Align the world and camera coordinates so they are coincident. Place the view reference point 4 units away from the origin backing away from the object in the direction of the negative z axis. Place a red light above and the left of the sphere as seen by the camera and a second green light above and to the right of the sphere. The lights should be approximately 10 units away from the center of the sphere. Make the sphere itself white, in other words high and equal values for red, green and blue diffuse illumination for the material of which the sphere is made.
Work with the illumination parameters until you have a sphere which is visible, largely appears red under the red light, green under the green light, and with two discernable specular highlights. Render your final ray cast image at 256 by 256 pixels. Include a rendered image with your submission.
Scene 2:
Starting with the scene model from Scene 1, add a cube such that it intersects the sphere and further so that over the entire area of the combined surface of the sphere and cube, roughly half belongs to the sphere and half to the cube. Use the white material specification from Scene 1 for the cube, but add a second material with a blue tint and use this for the sphere.
Move the light sources to infinity, and whiten their illumination relative to Scene 1. They should retain red and green tint but should include enough of the remaining colors to no longer appear totally saturated.
Where as before the camera was simply backed away from the object in the negative z direction in the world, in this rendering the camera should also be elevated and moved somewhat to one side so that the cube is viewed in a manner such that one vertex of the cube is clearly nearer the camera then the rest.
Scene 3:
In this scene you are to create a rendering of a sphere enclosed within a hollow cube in the style of the CS410 logo. For this scene experiment with light sources, camera placements, and focal lengths until you achieve a rendering generally similar to the logo. One large caveat, you are doing ray casting, so you will not have reflections nor will you be able to see through the sphere. Nonetheless, you will see distinctive shadow patterns on the surface of the sphere.
As with the previous assignment, your work will be turned in as a tar file submitted through RamCT.
The procedure for running your assignments, on a CS Department Linux Machine, will be automated and additional details will be supplied here.
No addendums at this time (10/27/2012)