fredag 18 juni 2021

Write a ray tracer guided by Jamis Buck's test suite

Background

Having seen people write their own ray tracers, I've been curious about writing my own. And for a while I also believed I just could sit down and write one, without any help, until I tried. At least I failed fast :)

Fast forward a few years to the moment when I listened to the podcast Developer On Fire, where the interviewer asks the interviewee for book recommendations and the book The Ray Tracer Challenge - A Test-Driven Guide to Your First 3D renderer by Jamis Buck is mentioned. I bought it and started coding.


About the book
The book explains the theory you need and contains unit tests in Gherkin, which means that you can translate them to whichever programming language you want to use. 
Here's an example of a test that subtracts a point from another, which should result in a vector:


I used C# and NUnit, which made my test implementation look like this:


The algorithms that make the tests pass are written in pseudocode, so you have to translate them as well.

What I learned
Test first
I really liked the test first way of coding. It catched errors early which made it easier to spot and correct the bugs. It was good to build up a safety net of tests, because the code got pretty math intense and would be pretty hard to debug without them.

Funny / not funny
The fun part was the coding and to see the resulting images. But creating sceneries and trying out different settings was not that fun, which makes it pretty useless to have my own ray tracer to play around with...

Recreational coding
Jamis Buck has also written a book about how to generate mazes, something he did when recovering from a burn out. He's sharing that story in the pod Corecursive.

Examples of created images

Here's two examples of images I created. 

Snowflakes
This is supposed to look like falling snowflakes. I made it after learning how to create cylinders and cones and how to group simple shapes together.



The making of a kitchen table

Here's after learning to do cubes and planes and manipulate them, like scaling in different directions, move them and give them color and patterns. Also tried to do a kitchen lamp, but found out that the shadow logic was too simple so that a transparent object shadows as much as an opaque object.

Yes, I had at hard time positioning the table legs :)


The code

It took me quite a while to finish the book. The commit history shows that I began in June 2019 and finished in June 2021. I worked with it in bursts and often had long periods of inactivity.

I skipped the code for matrix manipulation, I used the MathNet.Numerics nuget package instead to faster advance to the chapters that resulted in images.

My github repo for this project.

When searching for The ray tracer challenge at github, I get 254 repo hits in 10 languages, where the most are in Rust (51), C++ (48), C# (32) and Go (17).

After finishing the book I also noticed that people have posted their learning journey on youtube, like this playlist.