Austin Gebauer

Software Engineer | HashiCorp | Seattle, WA


Writing a Ray Tracer in Go

Published November 25, 2019

Table of Contents

Motivation

I’d been curious about how graphics worked since playing video games as a child.

I decided to take the time to learn about graphics programming this year. After doing a bit of research on rendering techniques, I decided to learn about a particular technique called ray tracing. Ray tracing can be used to render photorealistic scenes.

I followed a highly recommended book titled The Ray Tracer Challenge. It is a cohesive, hands-on, test-driven introduction to graphics programming. I personally recommend this book after having worked through it myself.

The purpose of this post is to share details on the building blocks of graphics
programming that I happened to find interesting along my learning journey.

Tools for the Job

I chose to write the ray tracer in my favorite programming language, Go. All else that I needed was my laptop and a text editor.

You can view the source for the ray tracer on my github profile at go-ray-tracer.

Rendering 1 - Projectile

My very first rendering was a projectile with a starting point, initial velocity, wind, and gravity.

The rendering demonstrates the use of points and vectors.

Rendering 2 - Clock

My second rendering is a clock. The clock has a pixel for each hour of 1-12.

The rendering demonstrates the use of matrix transforms (e.g., translate, rotate) on points.

You may need to squint in order to see the hour locations on the clock!

Rendering 3 - 2D Spheres

My third rendering is the first one that is actually ray-traced! It’s a circle that was produced by casting rays at a sphere and filling in colored pixels where an intersection occurred.

The rendering demonstrates the use of a line-sphere intersection algorithm and transformation matrices (e.g., scaling, rotation, shearing) applied to the spheres.

Rendering 4 - 3D Spheres

My fourth rendering is my first ever 3D rendering! Producing a 3D rendering was one of those moments that felt like magic. Those are the moments that keep me excited about programming.

The rendering demonstrates the use of the phong reflection model for pixel shading, computing normal vectors on a sphere, and vector reflection.

Rendering 5 - World

My fifth rendering is a ray traced world which includes 3 spheres sitting in a room with walls.

The rendering demonstrates the implementation of a camera with a field of view and view transformation matrix. The view transformation matrix orients the camera by specifying where to look from and to, and which way is up.

I found the following to be good reads for more on view transformation matrices:

Rendering 6 - World with Shadows

My sixth rendering is the same ray traced world as the last rendering but with shadows!

The rendering demonstrates using shadow rays to determine if a point is in a shadow or not. If a point is in shadow, the ray tracer will omit the diffuse and specular contribution and only use the ambient contribution to shade the pixel.

I also learned about shadow acne, which happens because computers cannot represent floating point numbers very precisely.

Rendering 7 - Still rendering…

I’ll be posting updates to this page as I learn new graphics concepts and render new images! Check back.