This repository contains the implementation of a physically based monte carlo path tracer in C++. The project avoids the use of graphics API's and attempts to implement simple physically based rendering effects from scratch.
This is a project I essentially come to in my free time and is something I intend to update sporadically. If you have read the code, or tried to create a scene and have found any flaws or errors in the way things have been done — do feel free to leave an issue!
Note: The above 3D model for the Head of Michelangelo's David bust was taken from here. Other .obj
models taken from The Stanford 3D Scanning repository
Noisy Render (Output) | Normal map | Albedo map | Denoised Image |
---|---|---|---|
Since the application runs on the CPU, samples per pixel needs to be limited to obtain reasonable render times (even with multi-threading).
The images shown above are denoised using Intel® Open Image Denoise. The pre-compiled zip file from their website (unzipped, includes a bin
and a lib
folder) needs to be moved into src/dependancies/
, for the shell script denoise
to work.
- Motion Blur
- Antialiasing
- Depth of Field
- Bounding Volume Heirarchies
- Multithreaded pixel processing
-
.obj
meshes - Importance Sampling
- HDR Environment maps
- Optimized and Multithreaded mesh BVH tree building
- Non-ideal materials and BSDF's (Disney BSDF)
- CUDA optimized
A sample binary has been uploaded with the repo (compiled on x86, as a 64 bit application), but its unlikely that it would generally work even on a system with the same configuration (try anyway, it just might).
CMakeLists.txt
is given and the project can easily be compiled using the cmake build system.
mkdir build && cd build
cmake ..
make
After compiling the project, the compiled binary (path-tracer
) can be found in the bin/
directory and is to be used with a single command line argument - the name of the scene in src/scenes/
. (The folder src/scenes/
contains implementation of all the scenes in this readme file)
./bin/path-tracer GlowRoom
Running this should show a progress bar, after which 3 images will be stored in output/noisy_render
, output/albedo_maps
, and output/normal_maps
. After these three images have been generated, the denoise
shell script can be run to denoise the image
./bin/denoise GlowRoom
The resolution of the output render and the samples per pixel have been hard-coded in main.cpp
OpenMP
was used for multi-threading the ray shooting and BVH tree building.- (stb_image and FreeImage) were used to handle images.
- GLM was used for mathematical data types (vectors, matrices, etc.) and operations.
- ImageMagick is required for conversions in the
denoise
shell script.
This project takes a lot from Ravi Ramamoorthi's course - An intro to graphics; and the repository and code largely takes its structure and features from Peter Shirley's book series.
The Disney BSDF, though poorly incorporated and incomplete, takes a lot from this repository and the corresponding blog articles. Inspiration was also taken, but to a lesser extent from tinsel from mmacklin and GLSLPathTracer from knightcrawler25.
And just like everyone ever who has written a path tracer, constant references were made to Physically Based Rendering by Matt Pharr, Wenzel Jakob, and Greg Humphreys and its repository.
This was more or less a pet project to be able to learn the fundamental basics of path tracing, and with every feature I added, I ended up wanting to add more.
I have licensed this project under the Zlib license, and do what you may with the code but I would highly recommend not to re-use the bsdf
namespace and the core::Disney
class, since some of the lobe calculations are off.