Before you start

You will be doing your work this semester in a class git repository. You will recieve a link to fork your personal class repository on github from my template repository. Before you get started on any of the assignments, you should use that link to create your repository, then clone yourself a copy of your personal repository following these directions.

To make sure you do not have last-minute problems, you must commit and push something to your repository by Tuesday, September 5th. This be anything from an update to the readme to the completed project.

The Assignment

For this assignment, you must write a C or C++ program that will render spheres using ray tracing. The input is in a simple text format called NFF, containing information about the view and objects in the scene. You will read an NFF scene from a file or stdin, and ray trace the single image described there. Rays that hit an object should be rendered in the sphere color, while rays that do not hit any object should use the background color of the scene. Do not try to include any of the more advanced ray tracing features you may read about (shadows, reflection, refraction, lights, etc.), we will get to those later. Your output should be an image file in PPM format.

balls -s 3

Input

For the base assignment, you should be able to trace balls-3.nff, which is checked into your trace directory. Additional NFF format scenes can be generated using a set of programs called the 'Standard Procedural Databases'. A copy of these programs may be found in ~olano/public/spd3.14/ on the UMBC GL Linux systems. While NFF format is relatively simple, it does contain many features we will not be using in this assignment. You should be able to read any NFF format file, but ignore anything you do not implement. For the basic assignment, you should at least handle the "v" viewing specification, "b" background color, "f" object material specification (just the r g b color part, ignore the rest), and "s" sphere specification. "c", "p" and "pp" are all multi-line, so you will at least need to recognize enough of those to know how much to skip.

Since the SPD programs produce their output on stdout, if your ray tracer takes its input on stdin, you can pipe them together:

~olano/public/spd3.14/balls | ./trace

Since that has 7381 spheres and can be slow to ray trace, using the -s option can yield a simpler models. For example, balls-3.nff with 830 spheres was generated with

~olano/public/spd3.14/balls -s 3 > balls-3.nff

Output

We are using PPM because it is an exceedingly simple format to write. See the specification for details. PPM files can be viewed directly or converted to other image formats for viewing. On the Linux systems, you can use "display" to view these files or "convert" convert them into most other image formats. If you are developing on your own computer, these programs are part of the ImageMagick package.

To create a PPM file, first you should store your image in an array of bytes in y/x/color index order:

unsigned char pixels[HEIGHT][WIDTH][3];

When filling in this array, remember that it is in y/x order, not the more familiar x/y order, with 0,0 in the top left corner of the image. The third index of the array is the color component, with red=0, green=1 and blue=2. Color values range from 0 to 255. Color values in your ray tracer should be floating point fractions, so you will need to scale to convert them to a byte. Be careful to check for overflow or underflow when mapping floating point values into a byte. For example, this would store a floating point color value g into the green component of the pixel at x=50 and y=25:

pixels[25][50][1]= (g<0) ? 0 : (g>1) ? 255 : (unsigned char)(g*255);

Once you've filled in the pixels array, actually writing the PPM file is quite simple. It is just a text header consisting of the characters, "P6" (identifying a binary color PPM file), text lines containing information about the image, followed by the raw binary data. Here's the complete C code necessary to write a PPM file:

FILE *f = fopen("trace.ppm","wb");
fprintf(f, "P6\n%d %d\n255\n", WIDTH, HEIGHT);
fwrite(pixels, 1, HEIGHT*WIDTH*3, f);
fclose(f);
jacks -s 1 tree -s 3

634 only

Also add the ability to trace cones and cylinders. Try the "jacks" or "tree" SPD programs to generate a scene with both spheres and cones.

Other people's code

Ray tracing is a popular rendering technique, and the Internet contains lots of resources for ray tracers in general and things like ray-object intersection in particular. Other than the PPM snippet above, YOU MAY NOT USE ANY OUTSIDE CODE. All code that you use must be your own.

Strategy

This is a big assignment. Start NOW, or you will probably not finish. No, really, I promise you will not be able to do it in the last two days. Even before we get to all of the details of the ray tracing itself, you can still start working on your file parsing.

I have created a separate page with some additional development suggestions.

What to turn in

Turn in this assignment electronically by pushing your source code to your class git repository by 11:59 PM on the day of the deadline and tagging the commit assn1. Do your development in the trace directory so we can find it. Be sure the Makefile will build your project when we run 'make' (or edit it so it will).

Also include an assn1.txt file telling us about your assignment. Include your name and campus ID at the top of this file! Do not forget to tell us what (if any) help you received from books, web sites or people other than the instructor and TA.

Check in along the way with useful checkin messages. We will be looking at your development process, so a complete and perfectly working ray tracer submitted in a single checkin one minute before the deadline will NOT get full credit. Individual checkins of complete files one at a time just before the deadline will also NOT get full credit. Do be sure to check in all of your source code, Makefile, README, and updated .gitignore file, but no build files, log files, generated images, zip files, libraries, or other non-code content.

To make sure you have the submission process working, you must do at least one commit and push one week before the deadline.