This is a raytracer written in 2.3k lines of C++.
Supported features:
-
Algorithm
- Path tracing
- Stochastic progressive photon mapping (SPPM)
-
Model
- Triangle, plane, sphere
- Bézier curve rotating around an axis (solved by Newton's method or triangulation)
- Triangle mesh (imported from
.obj
file)
-
Material
- Lambert reflectance
- Speculative material
- Reflective and semi-reflective material
- Refractive material. Reflection rate calculated by Fresnel-Schlick formula
-
Additional features
- Texture u-v mapping for mesh, plane, sphere and Bezier surface
- Normal texture for some objects
- Normal interpolation based on barycentric coordinates
- Soft shadow produced by light source sampling
- Super-sampling for anti-aliasing
- Depth of field
- Motion Blur
- Intersection finding accelerated by AABB and BVH data structure
- OpenMP multi-threading
You may refer to GitHub Release page for a more detailed report (in Chinese).
- Reflective and refractive balls:
./build/RT -i scenes/cornell-2ball.yml -o output/final/cornell-2ball.bmp -p4 -s1024
- Bezier curve:
./build/RT -i scenes/cornell-bezier.yml -o output/final/cornell-bezier.bmp -p4 -s512
- Reflective and refractive balls (SPPM version)
./build/RT_sppm -i scenes/cornell-2ball.yml -o output/final/cornell-2ball-sppm.bmp -p 10000000 -n 50 -r 0.008
- Color bleeding with path tracing
./build/RT -i scenes/bleeding.yml -o output/final/bleeding.bmp -p4 -s512
- Depth of field
./build/RT -i scenes/cornell-depth.yml -o output/final/cornell-depth.bmp -p4 -s1024
- Motion Blur
./build/RT -i scenes/motion.yml -o output/final/motion.bmp -p3 -s512
- Dragon (100k triangles)
./build/RT -i scenes/dragon.yml -o output/final/dragon.bmp -p4 -s512
- M4A1 (100k triangles)
./build/RT -i scenes/m4a1.yml -o output/final/m4a1.bmp -p4 -s512
- Caustic dragon with SPPM
./build/RT_sppm -i scenes/caustics.yml -o output/final/caustics.bmp -p 10000000 -n 50 -r 0.008
.
├── .gitignore # exclude some annoying files from git
├── assets # .obj, .mtl and textures, not included in this repo
├── CMakeLists.txt # yes, this project builds with CMake
├── LICENSE # GPL3 licence, use with care
├── Makefile # simply a script wrapper
├── README.md # what you are reading now
├── deps
│ └── vecmath # a tiny library for vector/matrix operation
├── results # output images (png and bmp)
├── scenes # scene description file stored in yaml
├── src # source code for our ray tracer
│ ├── core
│ │ ├── camera.cpp
│ │ ├── camera.h # perspective camera with depth of field
│ │ ├── hit.cpp
│ │ ├── hit.h # light hit the object
│ │ ├── light.cpp
│ │ ├── light.h # light sources emit rays
│ │ ├── material.cpp
│ │ ├── material.h # providing a few kind of materials
│ │ ├── ray.cpp
│ │ ├── ray.h # emitted from camera, or from light source
│ │ ├── texture.cpp
│ │ └── texture.h # uv mapping of texture
│ ├── objects
│ │ ├── bvh.cpp
│ │ ├── bvh.h # implementing BVH algorithm
│ │ ├── group.cpp
│ │ ├── group.h # a collection of objects
│ │ ├── mesh.cpp
│ │ ├── mesh.h # triangular mesh, powered by BVH
│ │ ├── obj_import.cpp
│ │ ├── obj_import.h # import mesh from obj file
│ │ ├── object3d.h # abstract base class of all objects
│ │ ├── plane.cpp
│ │ ├── plane.h # infinite size plane
│ │ ├── rotate_bezier.cpp # bezier curve rotating around an axis
│ │ ├── rotate_bezier.h
│ │ ├── sphere.cpp
│ │ ├── sphere.h # sphere
│ │ ├── triangle.cpp
│ │ └── triangle.h # triangle, supporting normal interpolation
│ ├── renderers
│ │ ├── path_tracing.cpp
│ │ ├── path_tracing.h # implementing path tracing
│ │ ├── photon_mapping.cpp
│ │ └── photon_mapping.h # implementing SPPM
│ ├── pt_main.cpp # main file for path tracing
│ ├── sppm_main.cpp # main file for SPPM
│ └── utils
│ ├── aabb.cpp
│ ├── aabb.h # axis-aligned bounding box
│ ├── ball_finder.hpp # a simple data structure to find spheres containing a point
│ ├── debug.h # some debugging/logging stuff
│ ├── image.cpp
│ ├── image.h # write image to file
│ ├── math_util.cpp
│ ├── math_util.h # random number generator, and some misc math functions
│ ├── prog_bar.hpp # showing progress bar for long-time rendering
│ ├── scene_parser.cpp
│ └── scene_parser.h # parse scene from yaml file
└── tests # additional correctness tests
├── ball_finder_test.cpp
└── bezier_intersection_test.cpp
Prerequisite:
- CMake no older than 3.14
- C++ compiler supporting C++17 and OpenMP
- Network connection to GitHub (for automatic dependency fetching)
After cloning the repository:
cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
Add -DRT_BUILD_TEST
if you want tests.
The compiled binary files RT
and RT_sppm
lie in ./build
. Both binarys requires a few command line arguments. Run with --help
to find out.
glog
: loggingfmt
: string interpolationtinyobjloader
: Wavefront.obj
file parserargs
: command line argument parseryaml-cpp
: yaml parser because we store the scene in a yaml filelodepng
: PNG encoder/decoder for reading PNG texturegoogletest
: tester