CSE 457

Introduction to Computer Graphics

Project 3 Help Session


This session is to help you get started with the third project: a raytracer.


Starting the Project

Wow! You're about about to write part of a raytracer. Raytracers are often big programs. They're very much the compilers of the graphics world: they compile some sort of scene description into an array of colours. Fortunately, this raytracer is actually pretty small. The current project is less than 5000 lines of code. Furthermore, a lot of that is user interface overhead that you can safely ignore. In fact, to complete all the basic project requirements, you need only change one file!

The first thing to do is download the skeleton project. Unpack it, and build it. Now run it. You get a window with two viewing panes. The left one shows you an OpenGL-rendered preview of the current scene. The right one will show you the final raytraced scene. Under the options menu, you'll be able to set a couple of important parameters to the raytracer, such as the maximum recursion depth and the size of the preview and raytrace panes. Changing the size of the raytrace pane can have a dramatic effect on tracing time. For big scenes, it might be useful to first try your raytracer with a really small output image to see that it appears to be working.

Run the skeleton application on "simple.out" in the scenes directory. What do you get? What does this tell you about the parts of the ray tracing that are already implemented? Also, be sure to try running the sample executable on the same scene, to get a n idea of what you're shooting for.


Converting VRML Files to Raytracer Files

At some point, it would be great to be able to render not just some planes and spheres, but a real VRML model, like your articulated model from project 2. On the main project description page, you can find out about vrml2out, a script available on blue to convert VRML files for you.

We're also attempting to provide an easier way to convert files. Try the following:

This directory is a "watched" directory. If you copy filename.wrl into this directory, a remote process will wake up and run vrml2out on it. The output will be placed in the same directory as filename.out. Additionally, any errors reported during conversion will appear as filename.err.

Be sure to copy your files into that directory, don't move them. The remote process consumes your copy, so if you don't save the original, you'll lose it.

Also, the process isn't very robust with respect to naming. Try not to copy in a file with a name that may conflict with others. My suggestion is to prefix all files you put in there with your initials. That reduces the chances of a conflict.


Important Files

Remember -- don't get bogged down with the details of all the files in this project. You can and should safely ignore most of them unless you're adding a complex bell and need to really dive in.

Here's a rundown of some of the more important files:

Vector3f.h
Some functions that allow you to manipulate three dimensional vectors. Unfortunately, this abstraction would be much better implemented in C++. Oh well. Get really familiar with this interface, because almost everything you do will be in terms of Vector3f objects.

SceneIO.h
You don't necessarily need to interact directly with the structures and functions defined in this file, but it's good to know what's in there. This file defines the SceneIO struct, which contains all the information about what's in the universe you're tracing. The associated .cpp file contains the routines that read and write .out files, so if you're thinking of extending the file format to add extra geometry or material parameters, you'll have to look in there.

Intersect.{h,cpp}
These files define the ray-object intersection tests. In the past, students have had to write all this by hand, but we feel that it's a painful experience without much educational benefit, so we've written the code for you!

You don't need to worry that much about these files at first. You may eventually find it useful to call the Intersect function yourself. Also, if you're thinking about adding arbitrary indices of refraction, you will have to modify Intersect.cpp.

Raytrace.cpp
Finally, we come to the most important file of all. Open this file and scroll down to the line in the Shade function that says "/* You will need to fill this in */". That's basically where your work goes. You need to flesh out this function to return to the caller the colour of this point on the given object's surface as seen from the given viewpoint.

Important Data Structures

Here's a slightly different view of the project: the data structures you'll care about when filling in your Shade function.
Ray
struct Ray {
 Point3f P;
 Point3f D;
}

A ray has an origin P and a direction D.

MaterialIO
struct MaterialIO {
 Color3f diffColor;
 Color3f ambColor;
 Color3f specColor;
 Color3f emissColor;
 float shininess;
 float ktran;
}

Instances of this struct get associated with objects in the world. These fields essentially give you all the properties of the surface that you need to implement the Phong shading model.

RTParameters
struct RTParameters {
 float rayeps;
 float minweight;
 int maxlevel;
}

The fields in this struct are used to help terminate the recursion in your Shade function. You might not use all three fields.

Important Functions

When you hit the "raytrace scene" menu item, here's what happens:
  1. CTraceView::RaytraceScene() is called. This does some MFC magic and calls...

  2. CTraceView::RenderScreen(). This is where raytracing as you have come to love it begins. For each pixel in the viewing plane, this function constructs a vector that passes from the viewpoint through that pixel. It then passes that vector to...

  3. TraceRay(). This function actually does the computation for a single ray. TraceRay() fires the ray off into the world and retrieves the first intersection with geometry. If there was no intersection, it calls ShadeBackground() and stops immediately. Otherwise, it obtains all necessary information about that intersection point and calls...

  4. Shade(). Shade is responsible for figuring out the colour of this point on the object with respect to the given viewpoint. It takes many parameters:
    • scene contains information about the lights, objects and camera in the scene.
    • level indicates the current level of recursion.
    • weight can be used to do adaptive recursion on transmitted and reflected rays.
    • P is the point on the object where the intersection occured.
    • N is the normal at P
    • I is a vector that points from the viewpoint to P
    • intersect contains information about the intersection point. When implementing refraction, intersect->prevIndex holds the index of refraction of the medium the ray is coming from and intersect->nextIndex holds the index of refraction of the medium the ray is entering.
    • color is an "out" parameter into which you should place the colour you want the viewer to perceive at this point on the surface.


Additional Information


Send questions or comments about the help session and handouts to Craig.