Rendering Techniques Assignment 4:
Accelerated Ray Tracing Flythroughs
Assigned: Wednesday, April 2, 2003
Due: Wednesday, April 16, 2003
Overview
For this assignment, you will speed up your ray tracer to scale better
to large numbers of primitives, implement a movable camera, and
demonstrater your program by generating a flythrough of a sizeable and
interesting scene.
Program Description
Your raytracer should now run with the following command line:
raytrace <scene description filename> <views filename> <image output file basename>
or
java raytrace <scene description filename> <views filename> <image output file basename>
The scene description format will be exactly the same as the previous
assignment (.rt3). The views file will specify a sequence of virtual
camera positions, each with a position, a forward direction, and an up
direction. The output file will just be a base name, to which your
program will append an image number and a ".ppm" suffix (you should use
a constant number of digits for the image number so that an alphabetical
listing of file names will remain properly sorted by frame number).
This assignment includes a sample
scene as well as a new test
executable (please let me know ASAP if you find new flaws in the
executable).
Acceleration Structures
In class we studied both bounding volume hierarchies and spatial
partitions for accelerating ray tracing. You may implement speedup
technique you like so long as it provides significant speedups for large
scenes (and provides identical output to an unaccelerated program). For
the test program, I chose to construct a bounding sphere hierarchy
because it builds on the programs existing ability to perform simple
ray-sphere intersection tests. An easy way to build such a hierarchy is
to take a top-down, recursive approach. Begin by computing an
axis-aligned bounding box containing all the scenes primitives. Surround
this box by a sphere to form the root node of your hierarchy. If the
number of primitives in the node is more than some threshold you
choose, break the box into 8 octants, and assign each primitive to one
of the octants (according to which octant contains the interior center
of the primitive). For each (nonempty) octant, find a bounding box, and
proceed recursively until the threhold is reached. In this scheme, each
primitive is associated with a single leaf node of the hierarchy.
Your bounding volume hierarchy (or other acceleration structure of your
choosing) will need to perform two functions. First, given a ray, you
should be able to compute the closest (positive) intersection point.
Second, given an shadow ray, you should be able to compute a filter
color describing how the light should be filtered according to the
primitives between the light and the primitive of origin (this would be
black if there is an opaque primitive in the way).
View File Specification (.rtv)
Each different image to be generated has a view in the view file. Each
view has an eye (camera) position, forward vector, and up vector. As
described in the following section, this is enough to specify your
complete camera coordinate system, so long as forward and up are
non-zero, non-colinear vectors.
# comment lines start with # and may appear anywhere
NUM_VIEWS: [number of views]
VIEW
EYE: <x> <y> <z>
FORWARD: <x> <y> <z>
UP: <x> <y> <z>
ENDVIEW
Moving Cameras
Each camera in the view file triggers the generation of an image file.
Your previous ray tracer assumed the camera position is (0,0,0), the
forward direction is (0,0,-1), the up direction is (0,1,0), and the
right direction is (1,0,0). The three vectors form an orthonormal
basis for your camera coordinate system. You should first convert the
view from the file into an orthonormal basis. There is no guarantee that
the forward and up vectors in the file will be orthogonal or normailzed.
A standard procedure to make an orthonormal basis is as follows.
Compute a right vector as the cross
product of the forward vector and the up vector (i.e. right =
forward x up). The cross product guarantees that the right vector is
orthogonal to both forward and up. Then compute a new up vector as the
cross product of the right vector and the forward vector (i.e. up
= right x forward). Then normalize the three vectors. You now have an
orthonormal basis which retains the direction of the given forward
vector and maintains the direction of the given up vector as much as
possible (if forward and up were already orthogonal, the up direction
will be unchanged). The only requirement here is that the given forward
and up vectors are non-colinear and non-zero.
Recall that the cross product
of two 3D vectors follows the right-hand rule and is defined as follows:
A = (Ax,Ay,Az), B = (Bx,By,Bz), A x B = (AyBz - AzBy, AzBx-AxBz, AxBy - AyBx)
Think of the x, y, and z coordinates of vectors in your previous eye
ray computation as the magnitude of the right, up, and backward vectors
of your camera coordinate system. Multiplying these values by the new
right, up, and backward vectors transforms them to the new, desired
camera coordinate system. You can use this transformation, for example,
to set up the position for the upper left corner of your screen and the
vectors for stepping right and down as you walk from pixel to pixel.
Note: Generating lots of images in a single execution may be a good
motivation to clean up any memory leaks!
Flythrough
To design an interesting flythrough, you need an interesting scene and
an interesting path. This is your chance to be creative. You may need to
write another small program to generate your scene, and it may be
convenient to write a small program to generate the path. You can design
things by hand, make creative use of randomization, or whatever you
like. Some simple paths to consider are straight lines, revolving the
viewing direction about a stationary view point, or moving in a circle,
etc. The demo will be given somewhat more weight in the grading of this
assignment than it was in previous assignments.
After generating a sequence of ppm images, you will need to apply some
lossy compression (the compressed tifs we have made so far are lossless,
but cannot compress dramatically). The simplest way is to convert to
JPEG images (.jpg). From Windows, you can perform batch conversion of
ppms to jpgs in XnView. You can use "convert" in unix to accomplish the
same thing. You can view your sequence in XnView in slide show mode or
in "animate" (as well as "display") in unix. Don't be surprised when you
notice lots of aliasing.
Deliverables
Submit a single .zip file containing the following:
- source code (you can include any auxiliary code you used)
- instructions for compiling and running
- interesting scene and view files, and sequence of .jpg images
- brief description of the flythrough (this can be comments at the
start of the files)
Note: there is a danger here of your submission becoming too large in
terms of file space. I would like to keep submissions down to a size of
1 MB, if possible. A 256x256 .jpg can look pretty reasonable with a file
size of about 10 kB, so you may be able to make as many as 100 images.
You may achieve much better compression ratios by converting your ppms
to a compressed movie format such as AVI, MPEG, or Quicktime. I may add
some additional information to this assignment to tell you how to do
this if you want to.
Final Words of Encouragement
I am hoping you will find the speedup and moving camera easy enough to
get done in the first week, leaving the entire second week for your to
explore creative ways to make a scene and a flythough. Good luck, and
have fun!
April 2, 2003