Programming Assignment #3
CMPSC 458 Computer Graphics, Fall 2019
Release Date: Friday, October 25, 2019
1st Intermediate Submission: Friday, November 8, 2019 (5 points)
2st Intermediate Submission: Friday, November 15, 2019 (5 points)
Final Submission: Friday, November 22, 2019
This assignment will require you to build a raytracer; a program that takes a
high-level description of a scene (where the objects, lights, and camera are)
and produces the image seen through that camera. You will do this without
using glm to render the image: you will use mathematical operations to
calculate the RGB value that should be at each pixel in the desired image.
According to wikipedia: In computer graphics, ray tracing is a technique for
generating an image by tracing the path of light through pixels in an image
plane and simulating the effects of its encounters with virtual objects. The
technique is capable of producing a very high degree of visual realism, usually
higher than that of typical scanline rendering methods, but at a greater
computational cost. This makes ray tracing best suited for applications where
the image can be rendered slowly ahead of time, such as in still images
and film and television special effects, and more poorly suited for real-time
applications like computer games where speed is critical. Ray tracing is
capable of simulating a wide variety of optical effects, such as reflection and
refraction, scattering, and chromatic aberration.
Start this project early, it might seem easy at first but many people have
struggled with this before.
Your raytracer must read a description of a file of the .ray format (see your
starter code). An example .ray file is shown in Figure 1. This file for1
mat includes descriptions of camera, background color, ambient light, diffuse/specular lights, and spheres & triangles with material properties and
texture images. Your raytracer must handle all of these accurately to receive
full credit. With your starter code comes a set of sample scenes useful to
test that your raytracer can handle all requirements. You will need to make
two new .ray files of your own, and you will need to submit renderings and
animations of your new scenes (as well as renderings of the sample scenes)
along with your code and readme.
Figure 1: A Sample Ray File.
Features are assigned points as follows:
15 pts – Sphere intersection and texture mapping.
15 pts – Triangle intersection and texture mapping.
10 pts – Diffuse and specular shading.
10 pts – Shadows.
10 pts – Recursive reflection/refraction.
10 pts – Animation.
10 pts – Two (or more) original scenes with some new materials with some
creativity in the scenes.
10 pts – Readme, Video (of the animation) and windows executable.
05 pts – Intermediate submissions.
For help, see the lecture notes and project slides on CANVAS. Chapter 4
(Ray Tracing) and Chapter 13 (More Ray Tracing) in the book are also very
helpful. For the animation, you should render many images and slightly
change one thing in each image.
For intermediate submission 1, you need to have the ray-triangle/sphere
mapping as well as the lighting and basic coloring completed. For intermediate submission 2, you need to have the reflection/refraction done and
the texture mapping completed. For the final submission, you need to have
You MUST have a rendering for each of the example ray files in your
4 Extra Credit
As usual, be creative, describe everything you do in the readme file, and
make things look nice to get more points. Some ideas:
– Good antialiasing.
– Animation with motion blur.
– Depth of field.
– Blinn blobs.
– Multiple object groups with bounding spheres.
– BSP Tree for speed up.
– Up to two additional object types (e.g. Procedural Object like a fractal or
– Procedural texture mapping.
– Loading an obj file and showing it in your work. This would require a new
type of object (You will want to also use BSP and make sure your code is
efficient before attempting this).
5 Additional Notes
The mathematic library is GLM but you cannot use the functions like ‘reflect’
or ‘refract’ within the library. You must code them yourself and any other
mathematics (except basic functions like cross product, normalization, or
anything else in the starter code).
The rows are parallelized using OpenMP so the code will run in parallel
which should give a significant speed increase. You can turn this off by
commenting it out if, like an animal, you debug using print statements.
6 Working with the Clusters
We have been granted access to the CyberLamp clusters for this semester.
You may use these resources run multiple ray files at the same time (which
will be useful for animation and for debugging).
The documentation for the clusters are https://wikispaces.psu.edu/display/CyberLAMP/.
This will be very useful in understanding how to connect and run the code
on the clusters (and if you are confused about any steps below). The clusters
use linux as their OS (like all clusters) so will need a basic knowledge of linux
to use these.
The steps run the code on the clusters is:
1. Move over the project. This can be done by either scp though I would
recommend filezilla (any sftp file client will work). In filezilla, you can
connect by connecting to sftp://email@example.com (where
abc123 is your PSU access ID). Once connected, move the project over
to the server.
2. Log onto the clusters via SSH or Exceed onDemand. I haven’t gotten
Exceed onDemand to work on linux so I would suggest you just use
SSH with X forwarding. You need to connect to ‘aci-b.aci.ics.psu.edu’
with your PSU user name. The ssh command will look like: ‘ssh -X
firstname.lastname@example.org’ (where abc123 is your PSU access ID).
This is detailed in:
3. Submit the Job. Once the project is there, you need to submit a job to
the clusters. For the purposes of this project, you can just use an interactive job (one which you can control in inputs rather than just running
a pbs script). We are using the cyberlamp class queue that limits us to 2
simultaneous jobs max. The code to request an interactive job is: ‘qsub
-I -A cyberlamp class -l qos=cl class -l nodes=1:ppn=8:gpus=1:shared
-l mem=4gb -l walltime=8:00:00’. This request 1 node (a computer),
with 8 CPUs, 1 GPU which shared memory, and 4 GB of ram. Look
here for more info on how to request resources:
4. Change directory with ‘cd’ to where ever you have put the project on
5. Create a directory for building the project (eg. ‘mkdir build’) and move
into the folder (eg. ‘cd build’).
6. You will need to load a newer complier and cmake. You can use the
command ‘module load cmake gcc’ to do this.
7. Then compile the code with ‘make -j8’
8. Now you can run it! In the build directory, use: ‘./Project 3/Project 3
SampleScenes/reflectionTest.ray y’ which will run ‘reflectionTest.ray’
and ‘y’ turns off the display while running it (necessary for the clusters).
If you want to run more than 1 instance of your raytracing program
at once, you either need to log into two separate terminals or submit PBS
scripts. The pbs script should contain everything from Step 3 onward. We
will go over this in class a bit. For now, you should use the interactive jobs.
7 Common Issues
• The code take a very long time to run.
Use a tool to measure how long each function takes to run to find what
is taking the longest and then figure out how to make it faster. You
should be good enough coders to code efficiently by now.
• The colors/textures have lots of dots in the reflection.
There is some machine imprecision when dealing with intersections.
Conceptually, you are finding the intersection between the ray and
the wall but rounding slightly inside of it and then hitting the wall
again when you reflect. You need to define a minimum intersection
distance (normally very small such as 1e-5) to deal with this imprecision
(like when you compare floats) which is typically called epsilon (see
Figure 2: Example image showing with and without a minimum distance
(epsilon) for intersections.