In this assignment you will create a simple ray tracer. This program will parse a text file that describes a 3D scene and the viewing parameters, and will produce an image of that scene.
For this assignment, you may work in groups of two if you want. Groups will receive a single grade. Any late days used will count against BOTH group members.
You can download an Windows OpenGL previewer for scenes here.
You can download an Linux OpenGL previewer for scenes here.
You can download an Windows sample solution here.
You can download an Linux sample solution here.
No skeleton code is provided for this assignment, although you can re-use the image reading/writing code from assignment 2 for image I/O.
Note: The previewers are provided for convenience only. They may or may not work perfectly; you should always compare your results to the sample raytracer. In particular, the previewers do not have reflections, refractions, or shadows. The exact look of the specular highlights might not be a perfect match. In addition, it is rumored that whoever wrote the previewer doesn't know his left from his right. ALWAYS COMPARE AGAINST THE SAMPLE RAYTRACER WHEN IN DOUBT. Note that the sample raytracer will only output BMP files, for historical reasons.
You do not have to worry about handling malformed scene input, although exiting gracefully rather than crashing is always appreciated.
The input file is a human-readable (and editable!) text file. Each line of the file should be processed separately; commands may not span lines.
Each line will begin with a word that will tell you how to interpret the rest of the line.
The rest of the line will be a space-separated list of parameters. The length of this list will depend on the word at the head of the line. Each word will always have the same number of parameters following it.
Note that "parameter" means "number", except for the output filename argument to "output_file". Certain commands use floating point numbers, while others use integers. For example, it doesn't make sense to specify a non-integral width and height for the film, so you can safely assume that those parameters are integers.
Lines that begin with # are comments and should be ignored,
The possible words and their associated arguments are summarized in the tables below: Your raytracer should properly implement the default values where specified.
Camera Parameters
camera px py pz dx dy dz ux uy uz ha This directive specifies the camera parameters. (px, py, pz) is the POSITION of the camera. (dx,dy,dz) is the viewing DIRECTION of the camera, and (ux,uy,uz) is the UP vector. "ha" is one-half of the "height" angle of the viewing frustum. The half-angle of the "width" angle can be computed using the aspect ratio of the output image (see below). The default is 0 0 0 0 0 1 0 1 0 45
film_resolution width height (width,height) is the desired resolution of the output image. The default is (640,480)
output_image filename "filename" is a string giving the name of the file to write the rendering to. The default is "raytraced.bmp"
Scene Geometry
max_vertices n A promise to the raytracer that no more than "n" vertices will appear in the rest of the file. This lets you allocate an array in which to store the vertices. There is no default. It is an error to specify a vertex before specifying max_vertices.
max_normals n A similar promise about the number of normals. There is no default. It is an error to specify a normal before specifying max_normals.
vertex x y z Adds the vertex (x,y,z) to the "pool" of available vertices. Vertices will subsequently be referred to by NUMBER, in the order they were received. The first vertex is number ZERO. normal x y z Just like the "vertex" command, this adds the normal vector (x,y,z) to the normal pool. Again, these will be referred to by number. triangle v1 v2 v3 Adds a triangle to the scene, using three NUMBERED vertices. This triangle is assumed to be flat, so its normal vector should be COMPUTED from the vertices. You should not assume that the vertices arrive in clockwise or counterclockwise order. normal_triangle v1 v2 v3 n1 n2 n3 Adds a triangle to the scene using three NUMBERED vertices and three NUMBERED normals. Each normal is associated with the corresponding vertex. These normals are then interpolated during rendering using the barycentric coordinates of an intersection. sphere x y z r Adds a sphere with radius "r" and centered at (x,y,z) to the scene. background r g b Sets the background color to (r,g,b). This color should be returned when a ray doesn't hit anything. The default is (0,0,0)
Material Parameters
material ar ag ab
dr dg db
sr sg sb ns
tr tg tb iorSpecifies the "current" material properties. This material will be applied to all subsequent primitives until a new materials is specified (this is like OpenGL "state"). (ar,ag,ab) is the ambient color of the object
(dr,dg,db) is the diffuse color of the object
(sr,sg,sb) is the specular color of the object
ns is the phong cosine power for specular highlights (ns=0 means no highlight)
(tr,tg,tb) is the transmissive color of the object,
ior is the index of refraction.
(sr,sg,sb) should be used to determine not only the color of a highlight, but also the contribution of a reflected ray.
For each channel (say red), ar, dr, sr, and tr act as Ka, Kd, Ks, and Kt (from the slide equations).
The default is 0 0 0 1 1 1 0 0 0 5 0 0 0 1, a matte white surface.
Lighting Parameters
directional_light r g b x y z Adds a directional light to the scene. This light has color (r,g,b), and shines in a direction (x,y,z). These lights are like the sun; very very far away. point_light r g b x y z Adds a point light to the scene. This light has color (r,g,b), and is located at the point (x,y,z). These lights radiate equally in all directions, but their energy falls off as 1/r2 spot_light r g b px py pz dx dy dz angle1 angle2 Adds a spot light to the scene. The light is located at (px,py,pz), and shines in the direction (dx,dy,dz). The two angles "angle1" and "angle2" define how the light falls off. For points at angles LESS THAN "angle1", the light should behave like a point light. For points GREATER THAN "angle2", the light contributes nothing. BETWEEN "angle1" and "angle2", the light should fall off smoothly. Although linear falloff is fine for this assignment, you might experiment with other falloff functions to give a more natural apperance. ambient_light r g b defines a scene-wide global ambient light to be applied to all primitives. The default is 0 0 0 (no ambient light).
Miscellaneous
max_depth n Certain scenes can cause your raytracer to get into an infinite loop (e.g. a hall of mirrors). This parameter sets a maximum recursion depth for reflected and refracted rays. The default is 5.
To get the full 100 points, you should add additional features to your raytracer from the list below (if you have another feature in mind that's not on this list, just ask). Note that some of these features will require you to extend the scene file format; that's OK, and you can extend the format any way you want, just make sure to submit sample scenes that show off your cool new features.
The number in front of each feature is how many points it is worth. Partial credit is available for features that "sort of" work.
Scene specification / Primitives
Complex Lighting
Sampling
Materials
Miscellaneous
Submit hw3.zip when finished. When submitting the file, if you are working in pairs, you only need submit the hw3.zip file for one person. In the submission page, enter the userid of the other person in the group.