Assignment 6 - Ray Tracing

[Logo]
Due: Midnight Wednesday, May 9, 2007


Project Description

You will build a program that will generate ray-traced images of complex scenes using the Whitted illumination model. You will start with an existing ray tracer and enhace it to achieve this. Note that access to this code is protected in the same way that access to the slides is protected, for similar reasons. Please do not put any of this source code publicly on the web or distribute it in any way.

Getting Started

The system you are starting with is a large collection of files and object-oriented C++ code. Fortunately, you only need to work directly with a subset of it. However, you will probably want to spend a bit of time getting familiar with the layout and class hierarchy at first, so that when you code you know what classes and methods are available for your use.

To install the skeleton source code, unzip the files from here if you are using Linux, and from here if you want to work on Windows. The skeleton code can load scenes and save images. It generates extremely simple "ray-traced" images. The pixels are shaded only by the ambient terms of the material at the ray intersections.

To get an idea of how a full blown ray tracer starting from this code works, look here for a version that will run under Linux, and here for a version for Windows. Some scene descriptions to use with both your code and the example code are here (Linux) and here (Windows). A description of what is in these scenes is here and the file format definition is here. To get an idea of how much the ray tracer (with some extra credit effects implemented in addition to the basic ones) can be extended to do, look here .

The starting point for where ray tracing begins, and where you will be needing to add a lot of functionality, is in the RayTracer.cpp file. This is a good file to start studying and exploring what methods get called and what they do. In addition, the raytracer features a debugging window that allows you to see individual rays bouncing around the scene. This window provides a lot of visual feedback that can be enormously useful when debugging your application. Here is a more detailed explanation of how to use the debugging window. More detailed information on navigating the code is here.

The skeleton code can run in both command line mode and interactive mode. Command line mode is considerably faster. Running without any arguments will execute the program in the graphics mode. For usage see 'ray --help'.

Required Functionality

  1. The skeleton code has no triangle-ray intersection implementation. Fill in the triangle intersection code so that your ray tracer can display triangle meshes. Use barycentric coordinates to support vertex interpolation, as elaborated below.
  2. Implement the Whitted illumination model, which includes Phong shading (emissive, ambient, diffuse, and specular terms) as well as reflection and refraction terms. You only need to handle directional and point light sources, i.e. no area lights, but you should be able to handle multiple lights.
  3. Implement Phong interpolation of normals on triangle meshes.
  4. Build your own scene description, showing off the full capabilities of your ray tracer. You can use one of the supplied ones as a starting point. Ray trace this to produce the best quality image you can arrange for. This will be turned in along with the code you produce.

Notes on Whitted's illumination model

The first three terms in Whitted's model will require you to trace rays towards each light, and the last two will require you to recursively trace reflected and refracted rays. (Notice that the number of reflected and refracted rays that will be calculated is limited by the "depth" setting in the ray tracer. This means that to see reflections and refraction, you must set the depth to be greater than zero!)

When tracing rays toward lights, you should look for intersections with objects, thereby rendering shadows. If you intersect a semi-transparent object, you should attenuate the light, thereby rendering partial (color-filtered) shadows, but you may ignore refraction of the light source.

The skeleton code doesn't implement Phong interpolation of normals. You need to add code for this (only for meshes with per-vertex normals.) The sample scenes include several simple scenes and three complex test scenes: trimesh1, trimesh2, and trimesh3. You will notice that trimesh1 has per-vertex normals and materials, and trimesh2 has per-vertex materials but not normals. Per-vertex normals and materials imply interpolation of these quantities at the current ray-triangle intersection point (using barycentric coordinates).

Here are some equations that will come in handy when writing your shading and ray tracing algorithms.

Extra Credit

Note that these extra credit projects can be arbitrarily challenging, and there are many of them. You cannot hope to do much, if any, of this, so don't harbor any illusions of completing them all, and consider very carefully how much will be involved in any of the ones that you choose before you start on them. Please see me if you are in doubt about this before you start. Also note that you will not want to choose to implement effects that will significantly slow down your ray tracer until after you have added a scheme for speeding up the computation. Accordingly, that extension is listed as the first item of extra credit.

Implement data structures that speed up the intersection computations in large scenes. There are two basic approaches to speeding up your ray tracer:

  1. Specialize and optimize the ray-object intersection test to run as fast as possible.
  2. Add data structures that speed the intersection query when there are many objects.
The biggest scope for improvment comes from approach 2, i.e. reducing the number of ray-object intersection tests. You are free to experiment with any of the acceleration schemes described in Chapter 6, ''A Survey of Ray Tracing Acceleration Techniques,'' of Glassner's book. Of course, you are also free to invent new acceleration methods. Make sure that you design your acceleration module so that it is able to handle the current set of geometric primitives - that is, triangles spheres, squares, boxes, and cones.

Implement simple anti-aliasing by super-sampling and averaging down. You should provide a slider and an option to control the number of samples per pixel (1, 4, 9 or 16 samples). You need only implement a box filter for the averaging down step.

Implement stochastic (jittered) supersampling. See Glassner, Chapter 5, Section 4.1 - 4.2 and the first 4 pages of Section 7.

Add a menu option that lets you specify a background image to replace the environment's ambient color during the rendering. That is, any ray that goes off into infinity behind the scene should return a color from the loaded image, instead of just black. The background should appear as the backplane of the rendered image with suitable reflections and refractions to it.

Deal with overlapping objects intelligently. In class, we discussed how to handle refraction for non-overlapping objects in air. This approach breaks down when objects intersect or are wholly contained inside other objects. Add support to the refraction code for detecting this and handling it in a more realistic fashion. Note, however, that in the real world, objects can't coexist in the same place at the same time. You will have to make assumptions as to how to choose the index of refraction in the overlapping space. Make those assumptions clear when demonstrating the results.

Implement spot lights.

Implement antialiasing by adaptive supersampling, as described in Glassner, Chapter 1, Section 4.5 and Figure 19 or in Foley, et al., 15.10.4. For full credit, you must show some sort of visualization of the sampling pattern that results. For example, you could create another image where each pixel is given an intensity proportional to the number of rays used to calculate the color of the corresponding pixel in the ray traced image. Implementing this bell/whistle is a big win -- nice antialiasing at low cost.

Add some new types of geometry to the ray tracer. Consider implementing torii or general quadrics. Many other objects are possible here.

Implement stochastic or distribution ray tracing to produce one or more or the following effects: depth of field, soft shadows, motion blur, glossy reflection (See Glassner, chapter 5, or Foley, et al., 16.12.4).

Implement texture mapping.

Implement bump mapping.

Implement solid textures or some other form of procedural texture mapping, as described in Foley, et al., 20.1.2 and 20.8.3. Solid textures are a way to easily generate a semi-random texture like wood grain or marble.

Extend the ray-tracer to create Single Image Random Dot Stereograms (SIRDS). Here is a paper on how to make them. Also check out this page of examples. Or, create 3D images like this one for viewing with red-blue glasses.

Implement a more realistic shading model. Credit will vary depending on the sophistication of the model. A simple model factors in the Fresnel term to compute the amount of light reflected and vtransmitted at a perfect dielectric (e.g., glass). A more complex model incorporates the notion of a microfacet distribution to broaden the specular highlight. Accounting for the color dependence in the Fresnel term permits a more metallic appearance. Even better, include anisotropic reflections for a plane with parallel grains or a sphere with grains that follow the lines of latitude or longitude. Sources: Watt, Chapter 7, Foley et al, Section 16.7; Glassner, Chapter 4, Section 4; Ward's SIGGRAPH '92 paper; Schlick's Eurographics Rendering Workshop '93 paper. This all sounds kind of complex, and the physics behind it is. But the coding doesn't have to be. It can be worthwhile to look up one of these alternate models, since they do a much better job at surface shading.  Be sure to demo the results in a way that makes the value added clear. Theoretically, you could also invent new shading models. For instance, you could implement a less realistic model! Could you implement a shading model that produces something that looks like cel animation? Variable extra credit will be given for these "alternate" shading models. Links to ideas: Comic Book Rendering,

Implement CSG, constructive solid geometry. This extension allows you to create very interesting models. See page 108 of Glassner for some implementation suggestions. An excellent example of CSG was built by a grad student in the University of Washington introductory graduate graphics course.

Add a particle systems simulation and renderer (Foley 20.5, Watt 17.7).

Implement caustics. Caustics are variations in light intensity caused by refractive focusing--everything from simple magnifying-glass points to the shifting patterns on the bottom of a swimming pool. An introduction, and a paper discussing a ray-trace project that included caustics.

Project Turn-in

You will need to use the "turnin" program on the departmental Unix machines to submit an electronic version for each part of the project before its respective deadline. If you developed your program on Windows, you will need to transfer your work to the Unix machines before submitting it (any ftp program should work).

To turn in the project, first clean your development area so that all *.o and binary executables are removed. Make sure to include your image and the scene description used to create it in the tree. Add a README file describing what you have done, where you have included your image and scene description, and how to build your system. Do not turn in the scene descriptions we have provided you unless you have modified them. Then, go to the parent directory and use the turnin command to submit your entire project tree:

  turnin --submit codeguru assignment6 ray

References