Project 3: Ray Tracing
Due: March 27, 11:59pm
Objective
The goal of this project is to write a ray tracing renderer. Your
program should be able to read scene data from a file according to a
defined scene description language. From this, your program will then
render an image of the scene and write out the image to a file. In this
project we will use just two geometric primitives: spheres and cylinders.
We will implement shadows and reflection, but not refraction.
Scene Description Language
-
fov angle
-
Specifies the field of view (in degrees) for a perspective projection. The
viewer's eye position is assumed to be at the origin and to be looking down
the negative z-axis (giving us a right-handed coordinate system). The
y-axis points up.
-
background r g b
-
Background color. If a ray misses all the objects in the scene, the
pixel should be given this color.
-
light x y z [r g b]
-
Point light source at position (x,y,z). Its color is optional (the default
is white). Your code should allow up to 10 light sources. Any objects in
your scene should cast shadows from these light sources, of course.
-
surface Kar Kag Kab Kdr Kdg Kdb Ksr Ksg Ksb N Krefl
-
This command describes the reflectance properties of a surface, and this
reflectance should be given to the objects that follow the command in
the scene description, such as spheres and cylinders. The first three
values are the ambient coefficients (red, green, blue), followed by diffuse
and specular coefficients. Next
comes the specular power N (the Phong exponent), which says how shiny the
highlight of the surface should be. The final value is the reflection
coefficient (0 = no reflection, 1 = perfect mirror).
Usually,
0 <= Ka,Kd,Ks,Krefl <= 1.
-
sphere x y z radius
-
A sphere with its center at
(x, y, z).
-
cylinder x y z height radius
-
A vertical cylinder with the center of its base at (x,y,z) and a given
height and radius. This command will only allow us to make cylinders that
have an axis parallel to the y-axis.
-
write filename[.ppm]
-
Ray-traces the scene and saves the image to a PPM image file.
Note on color specification:
Each of the red, green, and blue components range from 0.0 to 1.0.
Code Provided
All the provided source code that you will need for this assignment can be
downloaded here: prog3.zip.
We have supplied two utility packages that you should use to complete this
assignment. The first of these is a set of Command Language Interface
routines (CLI). These are provided so that you do not have to write a
parser for the scene description language. See below for more details on
the CLI routines.
The second set of routines that we provide are for writing a pixel in
a window and for writing an image to a file. You used these routines
for your first assignment. There are just a few routines that you'll
need to use:
-
gtBeginGraphics (xsize, ysize);
-
This command creates a framebuffer of the given size. If you are linking
to the SGI routines, this actually creates a window on the screen. If
you are on a different kind of workstation, it simply allocates the
necessary memory.
-
-
gtWritePixel (x, y, r, g, b);
-
This command writes a pixel to the screen at integer locations (x,y). The
color of the pixel is (r,g,b), where these are integers from 0 to 255 for
each of red, green and blue.
-
-
gtWriteFramebuffer(filename);
-
Write the contents of the framebuffer to a PPM file.
-
-
gtEndGraphics();
-
Deletes the framebuffer.
-
You can find a program called "irect.c" that uses these routines. This program allows you to type
commands such as "rect 0 0 50 50" to draw a rectangle. It demonstrations
how to use the CLI routines.
CLI Routines
The command line routines (CLI) provide a simple way to write and extend
an interpreter of ASCII files. The CLI routines automatically understand
the command "read". If you type the command "read rect_test" after
running the program "irect", it will read the commands in the file
"rect_test.cli" and execute them. Look at the contents of the file
"rect_test.cli" to see what a CLI command file looks like. This
particular file draws two rectangles and writes them to the file rect.ppm.
In this same way we will assemble our scenes to be ray traced. Reading in
the commands from a file saves us from having to type in the scene
descriptions each time.
When you run irect, if you type "help" or "?", it will print out a
list of commands that you may type. You can add new commands to the
program by adding lines such as:
COMMAND ("sphere x y z radius") {
float x,y,z;
float radius;
get_real (&x);
get_real (&y);
get_real (&z);
get_real (&radius);
create_sphere (x, y, z, radius); /* your own sphere-creation code */
}
You will need to create CLI commands for each of the commands in the
scene description language.
Scene Files
In the directory "results" are several test
scenes that are described by .cli files. Also in that directory are
the images that should be created by these scene files. The file "t0.cli"
is perhaps the most simple image, and you might use this scene as a
starting point.
Sample Results:










Suggested Approach
It is probably best to begin by making small changes to the "irect.c"
program to see how to add new commands to the CLI interpreter. After
you feel comfortable with this, then you can make dummy routines for
each of the commands that your ray tracer should understand. Then
replace each of the dummy routines with real code and you will be done! :-)
Once the shell of the program is ready, we suggest creating the main loop
that creates the primary rays (those from the eye). Start by printing out
the information about these rays to make sure that the numbers make sense.
Once you've got this loop working, then start on the ray/sphere intersection
routine. Don't bother shading the sphere correctly at first-- just color it
anything other than the background color. Once you've got a round object on
the screen, then work on the shading of the sphere. Finally, work on
ray/cylinder intersection.
Authorship Rules
The code that you turn in must be entirely your own. You are allowed
to talk to other members of the class and to the instructor and the TA
about high-level questions about the assignment. It is also fine to
seek the help of others for general C programming questions. You may
not, however, use code that anyone other than yourself has written.
Code that is explicitly not allowed includes code
taken from the Web, from books, or from any source other than
yourself. The only exception to this rule is that you should use the
routines that we provide. You should not show your code to other
students. If you need help with the assignment, seek the help of the
instructor or the TA.