15-462 Programming Lab 3: Ray Tracing
Due Tuesday, November 13th, 11:59 PM
In this assignment, you will be building a ray tracer. As already discussed in lecture, ray tracing is a powerful method to perform global illumination. Ray tracers are widely used to render photorealistic images and animations. You can try the interactive ray tracer  to see how the ray tracer works step by step. Examples of globally illuminated renders of a Cornell Box (some ray traced) can be found at Henrik Wann Jensen's page at . Also, you might want to take a look at the Internet Ray Tracing Competition for inspiration . Other useful materials on ray tracing are in the links section at the end of this handout.
At the end of this assignment, your ray tracer should be able to minimally handle opaque surfaces with lighting, shadows, reflections and texture mapping. Provided for you will be some starter code that performs some elementary parsing functions.
Sending out rays
The first step is to uniformly send out rays from the camera location. You will need to use backwards ray tracing where rays are sent from the camera, one ray per pixel. For your project submission, the image size must be 640x480. In the starter code, the width and the height have been reduced to help you debug more quickly. Your code shoulde work on any dimension.
When generating your scene, use a perspective projection "camera" with the camera properties specified by the input scene file.
This will allow us to standardize images for testing.
The next step would be to write code for intersections and texture mapping. The mathematical solutions for the intersection and texture mapping code are provided in the lecture notes and handouts.
In order to perform Phong shading, normals are required. For triangles, you can interpolate the x, y, and z coordinates of the normals at each vertex, and then normalize the length. We recommend using barycentric coordinates for interpolation of triangles. For spheres, the normal is simple to calculate from the center of the sphere.
You are also required to implement texture mapping. For triangles, this is very similar to interpolating normals. For spheres, we recommend using spherical coordinates for texture mapping.
The third step in the process would be to implement the illumination equations. The illumination equation for a surface point is given by:
I = (ka * Ia) + Ii * (kd * (L . N) + ks * (R . V)^n)
The slight modification we suggest you use is as follows:
ka = kd (the ambient material term is the same as the diffuse material term).
Note that in the ideal ray tracer, there should be no ambient effect. That would make the area the light cannot reach completely dark.
For materials with a non-zero specular component, you need to recurse (upto a maximum depth of at least 3). To add in the value of this recursive ray, use the following formula:
Ifinal = I + ks * Ir
The starter code  has been set up to be able to built in both Visual Studio 2005 and with the Makefile in Linux.
You will begin by implementing CalculatePixel(int screenX, int screen) in
RayTrace.h to return the correct color at that screen coordinate. The
screen-coordinates start with (0, 0) at the bottom-left corner up to
(WINDOW_WIDTH, WINDOW_HEIGHT) at the top-right.
The starter-code also allows you to dynamically change your position in 3D
Space using the (W,A,S,D) keys and the Arrow keys and preview the scene
set-up with a real-time fixed-function pipeline implementation. This should
allow you to check your camera and perspective calculations against your
Other important files include:
- starter.cpp : A ray tracer main program. There is no need to change this file except changing the window size to 640x480 before you hand in your program
- Scene.h : Your library for reading in the scene. It provides functions to read from an XML input file, properties of the camera, backgrounds, lights, 3 kinds of objects (sphere, triangle, and the model object), and object materials. The model object are objects composed of triangle meshes and stored in an object file. Scene.h can object the object file of type .3ds and .obj. You may want to read the comments to understand how to use it
- test.xml : A sample input scene file. You will need to create one like this as a requirement for project submission
- NormalRenderer.h : Contain the code to render the input scene using OpenGL (i.e. without ray tracing). This is a good example on how to read the input scene.
- RayTrace.h : The file to put your ray tracer implementation. Your ray tracer code will read in the input scene and perform ray tracing on each of the three kinds of objects in the scene.
- lab3readme.txt : Please fill in your andrew id, the status of your implementation, and any issues you have with your program.
There are 3 pre-defined object types in the starter code. Your program must support ray tracing for each of these object types.
- Sphere object defined by the center coordinate, the radius, and its material.
- Triangle object defined by the coordinates of 3 triangle vertices, the normal vectors, the material, and the 2-D texture coordinate mapping at each vertices.
- External model object which composes of multiple triangle objects. The starter code provide an interface to read the external model object from 2 file types (.3ds and .obj).
For each object type, Scene.h also defines the rigid body transformation parameters including rotation angles, scales, and translation units. These transformation allow you to create an ellipsoid and rotate model objects. Handling these parameters is an extra credit work. For the requirement submission, you can safely assume that the rotation and translation parameter will always be 0 and the scalation will always be 1.
Your program must:
- (10%) ray trace and correctly draw a sphere object in the scene
- (10%) ray trace and correctly draw a triangle object in the scene
- (10%) ray trace and correctly draw a model object in the scene
- (15%) read in material properties of an object in the scene, including the image files and texture coordinates, and add textures to your raytraced triangle objects and model objects. Use barycentric coordinates to calculate the texture coordinates at each pixel. You only need to be able to render triangle meshes. (don't worry about quads or polygons with more points.)
- (15%) correctly perform Phong shading by supporting ambient, diffuse, and specular lighting in your renderer. Interpolate the normals of the vertices of the polygons to determine the normals at each pixel to be used for shading.
- (10%) display shadows by not illuminating surfaces by lights from which they are occluded.
- (15%) correctly perform recursive reflection by creating a shiny surface and bounce rays off of it.
- (10%) be reasonably commented and written in an understandable manner-- we will read your code.
- (5%) be summitted along with XML scene files, the corresponding model object files (.3ds or .ob) and JPEG files displaying your ray tracing screenshots. Included screenshots must demonstrate all of the visible features of your ray tracer (shadows, textures, etc., but not bounding volumes). Put XML scene files and corresponding .3ds or .obj files in a sub-directory called scenes and JPEG files in a sub-directory called images.
- (required) Be submitted along with a readme file documenting your program's features and describing the approaches you took to each of the open-ended problems we posed here. This is especially crucial if you have done something spectacular for which you wish to receive extra credit!
- (required) Be submitted to your turnin directory as documented in the submission section.
Please submit your project to /afs/andrew/scs/cs/15-462/turnin/your_andrew_id/. Copy your modified src directory into that directory. When we run "make" in the src directory it should compile your program successfully. Also within asst3, make a sub-directory called scenes and images, and place your representative XML scene files and JPEG snapshots into the respectively sub-directory.
- Start this assignment as soon as you can. It is a significant endeavor, with many intermediate steps. If you wait until a few days before the assignment is due, you probably will not finish. This project is a lot of fun if you're not rushed, and if enough time is put in the end product is something fun that you can show off to your friends.
- Start by going through the code, the scene format, and getting a general idea of how things should flow in your program. The code is heavily commented, so please make sure to go through it and understand what needs to be filled in before you start your design & implementation.
- Read through the three chapters from the Introduction to Ray Tracing handout (link provided at the end of this page) [2,3,4].
- Think before you hack. There are a few corner cases that require some thinking.
- Leave time to work on your representative screenshots. Don't forget you need to demonstrate the features of your ray tracers.
Here are some suggestions for extra credit ideas:
Other cool things will get extra credit as well (talk to the TAs before you actually implement it).
- Recursive Refraction: allow transparent surfaces that refract rays.
- Distribution Ray Tracing - Soft Shadows, Depth of Field, or Motion blur:
cast more rays to create soft shadows, depth of field, or motion blur. Each of these individual features counts as an extra credit feature.
- Spatial Partitioning: put your model objects in an octtree, BSP tree, or spatial hash data structure to accelerate ray tracing them.
- Procedural texture mapping
- Environmental mapping
- Photon mapping
- Create addition types of objects in the scene
- Handle object transformation as discussed in the "Object Types" section above
Please note that the amount of extra credit awarded will not
exceed 10% of this assignment's total value.
 Starter code
 Introduction to Ray Tracing, Chapter 1 (CMU IPs only)
 Introduction to Ray Tracing, Chapter 2 (CMU IPs only)
 Introduction to Ray Tracing, Chapter 6 (CMU IPs only)
 Ray Tracing Materials on SigGraph.org
 Cornell box images by Henrik Wann Jensen
 Internet Ray Tracing Competition
 Interactive Ray Tracer