CS 428 - Fall 2011
Project 4: Ray tracing

Due electronically: Wednesday, December 7th, 12 noon

Image and scene file due: Tuesday, December 14th, 12 noon


Check this page frequently for updates and clarifications
(Significant changes or clarifications are marked with [Update])


Description

All of the assignments so far have used OpenGL to render the objects in the scene. Now it's your turn! Ray tracing is capable of producing more interesting lighting effects than a scan-line rendering approach. (Well, it is possible now to implement some of these effects using programmable hardware.) While the lighting model used is very similar to that of OpenGL, the difference comes in the rendering of shadows, reflections, and refractions (as seen in the image above), by using a better model of light transport.

Objective

From this assignment, you will understand how a recursive ray tracer works; from sending out rays through each pixel, to intersecting it with objects in the scene, to recursively sending out more rays. In the end, you'll find that it's just a large number of relatively simple geometric computations.

Program

You will be provided with skeleton code for this program, which supplies the main program structure. There is no graphical user interface -- you specify a scene file, and the program produces an image. Use the program "eog" to view the resulting images.

If you want to work on a Windows PC, you can use a program like pic2pic to convert from PPM files to something you can view (like TIF).

The relatively boring stuff (parsing the scene file, reading and writing image files, computing ray-object intersections, and transformations) has been done for you. You will have to write the main parts of the ray tracer; generating the rays (for each pixel), determining the relevant intersections with the scene, and computing the resulting color of the ray. You will also have to recursively send out additional rays (for shadows, reflections and refractions).

In some cases, you will find code that is a placeholder for what you need to write -- just remove it once you start on that part. In addition, you will probably have to add code elsewhere, and not just where the comment markers are. So don't feel confined by where these comments are placed.

The skeleton code for this project can be found (on the cereal machines) in the directory
      ~decarlo/428/proj4
Also included is a Makefile.

Note that we are not using OpenGL in this assignment.

A description of the scene file format is given in "README.running". Several sample scene files are provided (easy, easytex, hard, hardchecker) in the project directory, as well as their corresponding output in the directory (at 256x256 resolution)
      ~decarlo/428/proj4ex

Handing in

Hand in the following:

  1. all of your java files (no class files please)
  2. your makefile
  3. a description file descrip.txt
And then separately (after the program is due):
  1. your scene file
  2. a 512x512 PPM image of that scene

Hand in your image in PPM format (this is the format that your program will save it in, so you won't need to do anything here -- please don't convert it to another format). Your scene file should be substantially different from the sample ones provided (which simply are there to help you test your program). Feel free to hand in more than one scene file and image. Keep in mind you might need to let it run for quite a while (a day or more!) to get your image, if you implement a lot of the extra features.

You will need to create a tar archive to hand in, that contains your java files, Makefile, and description:

   tar cf proj4.tar Makefile *.java descrip.txt
Here are the instructions on how to hand in this file.

This assignment is a bit vague so that you can make a lot of the design decisions yourself. There are several approaches to the problems here. Use your best judgement to try and get the most useful result. Ask for help or clarification when you need it.

Program use

To run the program on a particular scenefile:     java Trace scenefile

A description of the scene file format is provided in the README.running file.

There are a number of command line options available (italicized words indicate you need to specify a particular value):

Data structures

The Scene class stores all of the information about a scene (objects, lights, materials, the camera, the matrix stack, some scene parameters, and the image being rendered). Aside from the image, all of this information comes from the scene file. The method Scene.render() is the main loop of the ray tracer, where a ray is cast out for every pixel in the image. An image of type RGBImage is produced.

The elements of the scene are subclasses of the abstract class RaytracerObject, which holds the specification of the scene element as taken from the scene file. Most of the methods in this abstract class are for parsing the scene file (the other classes that handle parsing are Parser, ParamSpec, MatrixStack and, SceneCommand). Note that you can print out objects in the RaytracerObject class---this is useful for debugging.

The following are the scene element classes: Camera, Light, Material and Shape. Each provides a specification of the scene element, along with methods for their manipulation and computation.

Particular shapes are defined as subclasses of Shape, and provide the low-level ray-object intersection routines. There are four types of objects defined: sphere, cylinder, cone and box (in classes Sphere, Cylinder, Cone, and Box). You are welcome to add more of your own (ask us for references for ray-object intersections for a particular object, if you can't find it).

The (matrix) transformations of the Shape are accessible using a number of accessors, which return a Matrix4d object: Shape.getMatrix(), Shape.getInvMatrix(), and Shape.getInvTMatrix() (for M, the inverse of M, and the inverse transpose of M). You'll use these matrices, and the various forms of the Matrix4d.transform method to transform the ray from the world to object space, and the intesection point and normal back to world space. Keep in mind that it affects the result whether you tranform a Point3d or Vector3d (it will add the proper w component of the homogenous coordinate for you when you pass these), so don't just convert back and forth between these indiscriminately.

There are three classes used for geometric computation: Ray (which represents a ray), ISect (which represents an intersection point, and other accompanying information), and Tools (which provide utility routines you will be using to compute reflected and refracted vectors, as well as scale colors).

You should be using the javax.vecmath package for all of your vector and matrix operations. Don't write out the code yourself for the calculations! (You will lose points this time if you do this.) Also, be sure to use Vector3d for vectors and Point3d for points, so your computations are correct.

The classes you will primarily be modifying are Scene, Light, and Camera.

Requirements

The following is a description of what is required to produce a fully-functional recursive ray tracer from the skeleton code. I suggest you proceed in the order they are listed, and test it when suggested (or even more often!).

When writing the above code, try to keep the computations efficient. Include checks that can prevent further recursive computation (don't send off a reflection ray if ks is zero, stop finding shadow ray intersections if you encounter an opaque object, ...). The time you spend doing this will be returned, as you'll be waiting less time for your images to be rendered. Avoiding excessive use of new in Java will also speed things up. Get your code working first, though, before optimizing it! (Good advice for any programming project.)

Extensions

The following is a list of optional extensions. The first three are required for graduate students.

Hints

The following are some suggestions...


428 Home