15-462 Computer Graphics I
Assignment 7 - Ray Tracing
150 points


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. An example of a Cornell Box, ray traced with soft shadows, by Henrik W. Jensen, can be found here.

At the end of this assignment, your ray tracer will be able to handle opaque surfaces with lighting, shadows, reflections and texture mapping. Provided for you will be starter code that will parse scene data from a file.

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. We would recommend the final images be 640x480, but for debugging purposes you would see faster rendering times for fewer rays. For example, halving each dimension of your image would cause only 1/4th of the rays to be sent out.

There are a number of ways to store the data generated from ray tracing. One way is to directly output each pixel to the screen as it's generated. If you do a flush and swap buffers, you can watch the scene being rendered. The disadvantage is that this may be a slow way to render; a speed up may be to write the data to the display every line, instead of every pixel. Another way to render is to store the data in an off-screen buffer, and send the whole data to the video buffer. This may be faster, as accessing the video buffer directly may be slow. To write to the video buffer, you should use the function glWritePixels(). The PIC_PIXELS macro can be used for JPEG writing. You could use the PIC_PIXELS macro to not deal with the OpenGL at all. Just allocate memory for a JPEG file, and use the PIC_PIXELS macro.

Intersection 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).

For rays 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

Scene Description Format

The first line is the number of objects in the file. There are three types of objects supported: lights, triangles, and spheres. Color values range from 0 to 1.

The format is as follows:
Number of Objects (1 integer)
Ambient Light (3 floats)
Then you can have lights, spheres or triangles.

  • sphere
    • texture name (up to 40 chars, or null)
    • position (3 floats)
    • diffuse color (3 floats)
    • specular color (3 floats)
    • shininess (1 float)
    • radius (1 float)
  • triangle
    • texture name (or null)
    • then 3 of the following:
      • position (3 floats)
      • diffuse color (3 floats)
      • specular color (3 floats)
      • normal (3 floats)
      • shininess (1 float)
      • s, t texture coordinates (2 floats)
  • light
    • position (3 floats)
    • color (3 floats)

Following is an example of a scene description file. It sets a gray sphere of radius 1 at (0, 0, -3), with no texture. It sets a white light source at the origin.

                 amb: .3 .3 .3
                 tex: null
                 pos: 0.0 0.0 -3.0
                 dif: .3 .3 .3
                 spe: .5 .5 .5
                 shi: 1
                 rad: 1
                 pos: 0 0 0 
                 col: 1 1 1

Feel free to extend or modify the format for any extra credit features that require it, e.g. refraction. Make sure to document these extensions in your README file.

Creating Test Scenes

From the mobile animation and coaster assignments, some of you will be familiar with creating objects in Alias | Wavefront's Maya or 3D Studio Max. Feel free to use these in your scenes; once you've created the objects in Maya, find a way for your program to read in all the triangles from the object and render them with your ray tracer. This will allow you to render very complex scenes with your ray tracer, like the ones found at the Internet Ray Tracing Competition.

Even if you don't use one of these tools, we require that you set aside some time to create a good scene for us to run your ray tracer on. It should be a non-trivial scene that shows off some of the functionality you may have implemented for extra credit, or possibly one that has a large number of triangles/spheres in it with complex reflections.

Think before you hack!

Past iterations of the course and of this assignment have shown us that many students rush into implementing their ray tracers without giving much thought to the design and architecture of their solution. We strongly encourage you to plan out the pieces of your ray tracer coherently before you get started on writing any code. Furthermore, this will give you a good opportunity to clear up any lingering doubts you might have about the assignment itself before getting started with the implementation. Be warned - there will be very little OpenGL programming in this assignment.

Ray tracers can be implemented in a very elegant fashion using an object-oriented (C++, Java) or functional (OCaml) approach. Although we provide starter code in C, you are encouraged to start from scratch with your own design using C++ or OCaml.

Functionality Requirements

This is the list of requirements for this assignment.

  • Triangle Intersection (20 points)
  • Sphere Intersection (20 points)
  • Triangle texture mapping (20 points)
  • Sphere texture mapping (20 points)
  • Sphere & triangle Phong shading (10 points)
  • Shadow rays (10 points)
  • Animation or Still (10 points)
  • Recursive reflection (15 points)
  • Good test scene for ray tracer features (10 points)

The above list constitutes 135 points of the 150 point assignment. For the other 15 points, and up to 30 points possible extra credit, you may choose features to implement from the following list.

  • Recursive refraction (10 points)
  • Good antialiasing (15 points)
  • Motion blur (15 points)
  • Spatial partition: octrees or BSP trees (45 points)
  • Blin blobs (45 points)
  • Soft Shadows (20 points)
  • Bounding Box or Sphere optimization (15 points)
  • One or two additional types of objects in scene (10 points/class)
  • Procedural texture mapping (15 points)
  • Photon mapping (45 points)

Animation or Still

In addition to your program, you are also required to hand in an animation or still picture in the form of JPEG files.

  • The animation or still should be something that shows off your features.
  • For example, if you implemented a spatial partition, your scene could be more complicated.
  • The animation should consist of a series of JPEGs stored in a subdirectory called movie/.
  • If you do a still, please create a directory called movie/ and place 60 copies of your still, numbered 000.jpg to 059.jpg. We will run the frames at 15 fps.
  • The JPEGs should be numbered consecutively starting from 000.jpg.

Handin Instructions

In your graphics handin directory, /afs/andrew/scs/cs/15-462/students/user/, create a subdirectory called asst7/. In that directory submit all your files (source code, Makefiles, texture maps, scene descriptions, ...). Make sure you include a Makefile.

Include a README file that documents the functionality of your ray tracer. Also, list all the scene files that show off your features and document any extensions you made to the scene description format.

Starter Code

The starter code (in C) takes a file at the prompt which contains a scene description. It fills global structures containing triangles, spheres, and lights.

As usual, we expect your code to compile and run in the WeH 5336 graphics cluster.


  • Start early! This is a difficult assignment, but can be a lot of fun to work on without the worries of time-pressure.
  • Read through the three chapters from the Introduction to Ray Tracing handout.
  • Consult the TA's to clear up any lingering doubts before you begin.
  • Think before you hack!
  • Leave time to work on your stills/animation.


[ Home | Schedule | Assignments | Software | Resources ]

Frank Pfenning