/ CMSC 435/634 Spring 2021, Assignment 1

Due February 3rd (assn1a)

You can use your own computer (Windows, Mac or Linux) for this class. If you do not have a suitable computer, it is possible to arrange remote access to computers on campus. Contact me directly if you think you will need this.

The first part of this assignment is just to make sure you are set up and will be able to submit later.



You will need some local git tools. It will not be enough to just use the github web interface. A graphical user interface for git can make some operations easier, though it is good to develop some familiarity with the command-line git tools as well.


CMake is a cross-platform tool for making build files (Visual Studio solutions, XCode projects, Makefiles, etc.) from a common text-file description. This will help make sure we don't actually need to use the same OS as you to build, run, and test your code.

C++ tools

You will be using C++ for all of the programming assignments this semester.


You will be doing your work this semester in a class git repository.

  1. If you do not already have an account on github, make one
  2. Fill out this google form to tell us your github username (you will need to be logged in with your umbc account to access the form).
  3. Once you receive and accept the GitHub team invitation email, you will be able to see the class repository at github.com/UMBCGAIM/graphics21.
  4. Fork the repository, then in "Settings" > "Manage access" for your fork, add "olano" with Admin permissions. See the in-class demo, or look at some of the many git tutorials online.
  5. Make your own local clone of your personal repository on your computer. You'll see a trace directory, containing a CMakeLists.txt file. You will put your source code for the first assignment in this directory.

Initial commit

To make sure you do not have last-minute problems, you must set up your git, make a local clone, and do an intial commit, push, and tag to your repository by February 3rd.

  1. Create an assn1a.txt file at the top level of the repository and put whatever comments you want in there.
  2. Use your local git command-line or GUI tools to add and commit that file.
    • Using the command line, "git status" lists files that might need to be committed.
    • "git add" listing individual file names or "git add ." adds them to the list to be committed.
    • "git commit -m 'message'" commits those files with a descriptive message.
  3. Push those changes back to github.
    • Command line: Just "git push".
  4. Tag that commit with an "assn1a" tag, and push that tag to github. Git tags are typically used for software releases. We will be using tagged releases for each assignment so we know which commit to grade, even if you keep working and pushing changes after your submission commit.
    • Command line: "git tag assn1a" to tag locally.
    • Then "git push origin assn1a" to push that tag to github.

Due February 14 (assn1)

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 subset of the rayshade (.ray) file format, containing information about the view and objects in the scene. You will read a .ray scene from a file, and ray trace the single image described there. Rays that hit an object should be rendered in the object 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 -r 8


For the base assignment, you should be able to trace balls-3.ray, which is checked into your trace directory. Additional .ray format scenes can be generated using a set of programs called the 'Standard Procedural Databases', using the "-r 8" command-line option to generate rayshade-formatted output. A compiled copy of these programs may be found in ~olano/public/spd3.14/ on the UMBC GL Linux systems. While rayshade format is relatively simple, it does contain many features we will not be using in this assignment. For the basic assignment, you should handle "background", "eyep", "lookp", "up", "fov", "screen", "surface", and "sphere". For "surface" you only need to handle the "diffuse" keyword. For anything in the file that you do not handle, just keep reading until you find one of those keywords.

To generate a test file on GL:

~olano/public/spd3.14/balls -r 8 > balls.ray

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

~olano/public/spd3.14/balls -s 3 -r 8 > balls-3.ray


We are using the PPM image file format because it is exceedingly simple to write. See the specification for details. PPM files can be viewed directly or converted to other image formats for viewing. The Mac Preview app will open these files. On Windows or Linux, the ImageMagick package includes a "display" program to view these files and "convert" convert PPM into most other image formats. Alternately, the Gimp package can both display PPM images and save in other formats.

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 = new unsigned char[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*WIDTH*3 + 50*3 + 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 stdio-based 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);
balls -s 3 -r 8 gears -s 2 -r 8
From balls-3.ray From gears-2.ray

634 only

Students who are taking this class as CMSC 634 should also add the ability to trace arbitrary polygons ("polygon" in the .ray file). Examples of this include the orange floor in the balls scene, or any scene generated by the "gears" SPD program.

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 strictly your own.

Using CMake

To use CMake, create a "build" directory under "trace".

Command-line cmake



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.

Also include an assn1.txt file at the top level of your repository telling us about your assignment. Tell us what works, and what does not. Also tell us what (if any) help you received from books, web sites, or people other than the instructor and TA.

You must make multiple commits 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 will not count as incremental commits. Do be sure to check in all of your source code, but no build files, log files, generated images, zip files, libraries, or other non-code content.