pathtrace1.png

Path Tracer

As an ongoing hobby project, I created a ‘path tracer’ renderer. Designed to render ‘offline’, it offered me the chance to learn about different techniques that would not be practical in realtime (or at least weren’t until the release of RTX graphics cards)!

 

Design

Advanced Graphics

With reference to “Physically Based Rendering - From Theory to Implementation” among other resources, I utilised a Monte Carlo path tracing technique. I was able to experiment with BRDFs/BSDFs and the balance of light reflection to transmission. This was enlightening for me when it comes to PBR rendering.

Lights are direct sampled, greatly reducing the noise of standard path tracers. This was further reduced with supersampling and post processing.

Pixel colour is stored with HDR, and rendered images are saved in a Radiance HDR file format. This allows for ‘toning’ to be done post-render.

pathtrace2.png
 

Fast rendering speed

I wrote the renderer in Rust, to explore its promises of memory safety and “zero-cost abstractions”. I found these both very true. Despite the use of abstractions such as .map and other functional programming techniques, it runs with performance comparable to that I would expect from C++.

Optimising memory usage was simple as Rust makes copies and heap usage very explicit. This was useful when designing for a multi-threaded architecture.

Multithreading is achieved by dividing each image into rectangular cells, which are rendered concurrently using a thread pool. Optimising the balance of number of cells, number of workers, and amount of supersampling had a significant impact on performance.

Current Work

I am currently working on a project using a hybrid solution of ray tracing (rather than path tracing) and rasterisation in realtime.