Happy New Year
I wish you a Happy New Year !!!
For me it’s also a chance to do a review of the year 2017. Most of it I spend on a Rust implementation of PBRT (beside working for The Mill and making sure we can deliver our moving images, rendered most of the time with Arnold).
Rust Implementation of PBRT
The image above was rendered using my own implementation of the PBRT renderer, written in Rust. It probably started at the end of 2016, when I received the third edition of the Physically Based Rendering Book, which comes with the full source code of a renderer. I purchased already the first edition, skipped the second one, and seeing the third edition with contributions from Jakob Wenzel, the author of another renderer, called Mitsuba, finally inspired me to try to convert at least some of the C++ code to another language, called Rust.
To be honest the intention was to learn this new language, Rust, and by taking a well designed (and hopefully fast) C++ implementation, which needs multi-threading to fullfill its task of creating images, I hoped to run into some challenges, regarding how to archieve the same results as with C++. And surely I did. First you learn about the so-called borrow checker, which simply prevents to compile certain code patterns you might be familiar with from C or C++. The Rust compiler is pretty strict and is designed to prevent for example dangling pointers.
So the first couple of month I spend on implementing basic structs (there are no classes in Rust) and their related methods. Vectors, points, normals, bounding boxes (2D and 3D), rays, etc. The nice thing about Rust is that we have something like Doxygen built into the language and related documentation strings. You can still see part of the documentation being built from the source code for the structs mentioned above on my web-site.
There were many more structs and methods I had to implement before I actually could render the first image, which was done back then single-threaded. By then I had somehow managed to fight the borrow checker successfully and if I ran into problems I got really helpful responses on the Rust programming language forum. The first test scene was two spheres on a ground plane (two triangles):
If you use Rust nightly you still find example code which can render the same scene and variations of it:
> rustup install nightly > rustup default nightly > cargo test --release > ./target/release/examples/pbrt_spheres_differentials_texfilt -h Usage: ./target/release/examples/pbrt_spheres_differentials_texfilt [options] Options: -h, --help print this help menu -c, --checker use procedural texture -i, --image use image texture -n, --none use no texture -m, --matte use only matte materials -v, --version print version number
End of May I released the first version which was multi-threaded, but soon I realized that I had to implement a parser for the PBRT scene description. In July I was able to parse several scene files and render e.g. the Cornell Box with direct lighting:
Shortly after, in August, I was able to render with uni-directional path tracing:
I also implemented ambient occlusion, which was added to PBRT after the book release, and in the future I will add even more integrators. Shortly after I extended my already existing multi-exporter for Blender to export PBRT files along with the Luxrender scene description. This quickly gave me access to more test scenes:
Look at the release notes for more details or the download section, where you can find scenes in various scene description formats for different renderers. I also published two blog posts, one about the Conference Room, another one about the theater scene, which I both used already with other renderers to compare results. Also mentioned in the release_notes, I worked on some basic motion blur support (and depth of field):
I think this is good progress so far. I wouldn’t mind if I would find some contributers, so far I’m the only one working on rs_pbrt. If you want to participate, please contact me via the email address mentioned on the imprint page. I will definitely work on bi-directional path tracing this year, but I can’t predict where this project is going. My excuse to learn the language Rust is more or less fullfilled, I learned a lot about the language and I do like it. I ran into a bottleneck regarding the BVH acceleration structure and solved it with the help of profilers (see all the details here). In the end you will just have another implementation of an already functional renderer, which was originally developed using C++. It will be interesting though if the Rust version can be optimized to render with the same speed as the original. More important to me was that it was fairly easy (and safe) to implement multi-threaded code with Rust and that the community was very helpful whenever I ran into problems.