Ray Tracer
CS 130
I took UC Riverside's undergraduate Computer Graphics class (CS130) in the Fall of 2025. This ray tracer was the first project we were assigned in that class.
In my opinion, CS130 is the best computer science class at the entire university. It's taught by Craig Schroeder, who is an excellent professor. His teaching assistant is also extremely good.
The Project
The professor gave us a project template that included all the code necessary to get started quickly. All the boilerplate for input parsing and vector arithmetic was already implemented for us. Our assignment was to implement the actual ray tracing math.
Due to the class's academic integrity policy, I cannot publish the code I wrote for the project. I could get around that restriction by reimplementing the entire project in a different language, but I don't currently have enough spare time for that.
Instead, I'll just show and explain some of the scenes that it can render.
We started the project by implementing the algorithm for casting rays from the
camera, as well as the algorithm for ray-sphere intersections. That let us render
flat scenes like this:

Then we implemented the Phong shader
for basic diffuse and specular lighting. This was the most difficult stage of the
project for me. Not because the math is hard, but because I hadn't yet developed
the intuition for debugging vector math. Also because I didn't realize that the
Blinn-Phong model is not equivalent to the Phong model (I spent at least an hour
scratching my head trying to figure out why my specular reflections were
ever-so-slightly wrong):

The whole point of a ray tracer is to be able to accurately render reflections
and refractions, so that was the next stage of the project:

Handling different indexes of refraction is trivial:

Finally, we extended the program beyond rendering spheres and into the realm of
meshes:

We also implemented UV texture mapping. By this point in the project, I had
learned the importance of working out all the math on paper before ever touching
the code. That made the process of implementing meshes and UV mapping very
straightforward. (I nearly got my implementation right on the first try!):
