The Ray Tracer Challenge in Rust
Tags: rust, github
Published: 2019-09-18 10:57:35

## The time has come..

This summer I started to learn Rust by using [The Ray Tracer Challenge book](https://www.amazon.com/Ray-Tracer-Challenge-Test-Driven-Renderer/dp/1680502719) and implementing it in Rust. It's been a side project but extremely fun and challenging. I also promised to publish my code on GitHub over two months ago, so this is long overdue. The code is not complete, there are several chapters that I still haven't worked thru so expect to see some more changes over time.

Anyway - now I will expose my stumbling steps in Rust to the world. After some consideration I decided to actually publish the entire Git repo with history intact rather than just start from the current position. It is a bit embarrassing  to look at some of the earlier things I did, but I fully expect the current state of the code to be embarrassing for my future self, so what the heck...

https://github.com/magnusstrale/raytracer

## Some reflections on the code

One thing I found interesting when going over the Git history was my ambivalence in deciding how to deal with matrices (a fundamental part of ray tracing), more specifically how the data should be stored in the Matrix struct. The biggest hurdle was the fact that an array in Rust has to have a fixed size, since the size of the array is part of its type. You either have to use a [Vec](https://doc.rust-lang.org/std/vec/struct.Vec.html) (vector, resembling a variable size array) or provide different functions to call depending on the array size.

The solution I have right now (maybe I'll change my mind again in the future) is to internally always use a 4x4 array to store the data, even when working with 2x2 or 3x3 matrices. The main reason for this decision was that I wanted to have the [Copy trait](https://doc.rust-lang.org/std/marker/trait.Copy.html) implemented for Matrix (which is not possible when using a Vec). This allows for the expressions with matrix arithmetic look much cleaner since I don't need to put in a lot of &'s to borrow the data. See [here](https://github.com/magnusstrale/raytracer/blob/1c2e19ec913c70ef7161608a67d09c7d5861d662/src/matrix.rs#L561) for an example of "clean" matrix multiplication.

There are earlier states of the code base where I have used a Vec and it's possible that I'll switch back to Vec again in the future. 

## Next steps

- Finishing the book. There are several chapters in the RTC book remaining and I intend to continue until the end.

- Performance optimizations. Right now I've just tried to keep the code as clean as possible, but I look forward to performance tuning. I will play around with Vec vs Array, the possible performance implications of Copy etc.

- Target WASM / browsers for ray tracing. I want to get more experience with Web Assembly and the Rust tool chain for producing WASM.

- Build a Ray Tracing web site. Having something fairly simple where it will be possible to interactively create a world and then get a nice ray-traced image from the WASM package running in your browser. Of course I will use use Rust for any server-side coding.

## Closing remarks

Feel free to browse the code [here](https://github.com/magnusstrale/raytracer), download and play around with it. I will be very happy for any comments on how to improve the code, especially if there is anything in Rust that can be leveraged to reduce the amount of code or make it more idiomatic.