Code
darts is a minimalistic skeleton for a Monte Carlo ray tracer, written in C++17. The name is an acronym for The Dartmouth Academic Ray Tracer Skeleton while also being a nod to the random dart-throwing-like process involved in Monte Carlo ray tracing. It runs on recent versions of Windows, Linux, and macOS and provides the foundation for the programming assignments we'll be doing in this class.
Design philosophy
The primary goal of darts is educational. As such, its design aims to balance several educational objectives
- minimize "time to first pixel" – allowing you to start producing images quickly
- don't provide many rendering features "out of the box", instead allow you to learn by implementing these yourself while steering you towards a modern full-featured ray tracer design
- keep the core rendering-related code base small but extensible, while relying on a few, self-contained libraries for supporting code
- keep the build system simple and reliable across major platforms
You can think of darts, and the accompanying assignments, as filling the gap between the simplicity of Peter Shirley's Ray Tracing in One Weekend series of books, and the complexity and completeness of more sophisticated research-oriented renderers like PBRT or Mitsuba.
The assignments are designed to help you explore and extend the darts code, while simultaneously progressing through the Shirley books and towards the PBR book. In the first few assignments, you will fill in empty methods left in the starter code, and test them using the tools provided with each assignment. In latter assignments, you will need to figure out what functions and classes you will need to add to the code to accomplish the tasks.
While darts cannot (yet) produce images, after stepping through the assignments you will steadily add features that allow you to render images like the ones below, with the photorealistic lighting characteristic of ray tracing:
Features
Darts provides many features that are tedious to implement from scratch, including:
- A JSON-based scene file loader
- A nice command-line interface with option parsing, and a text-based progress bar for long operations
- Basic color/vector/matrix/ray/bounding box classes
- A high-quality pseudorandom number generator
- Support for loading and saving images in a variety of formats (.png, .jpg, .exr, .hdr, etc.)
- Support for loading Wavefront OBJ files
Code organization
The codebase has the following high-level structure:
Directory | Description |
---|---|
include/darts | Contains the header files for the core classes, algorithms and data structures of darts |
src/ | The core C++ source files, as well as most added files will go here |
scenes/ | Example scenes and test datasets to validate your implementation |
reports/ | The skeletons for webpage reports for each of the assignments |
documentation/ | The source and configuration files for this course website, and the Doxygen documentation |
CMakeLists.txt | The main CMake build file which specifies how to compile and link the code |
cmake/ | Additional CMake files (you likely won't have to look at this) |
Darts uses modern CMake, and the CPM.cmake package manager for a particularly clean and simple build set up. At configuration time, the CMake build system automatically downloads (from other GitHub repositories) several open source libraries, including:
Dependency | Description |
---|---|
cli11 | Command line parser for C++11 |
filesystem | A tiny self-contained library for manipulating paths on various platforms |
flip | A tool for visualizing and communicating errors in rendered images |
fmt | A modern formatting library/replacement for C's printf and C++ streams |
linalg | Single header C++11 vector math library inspired by the syntax of shading languages |
nanothread | A minimal thread pool library for task parallelism |
nlohmann-json | A JSON parsing library for modern C++ |
pcg32 | A tiny self-contained pseudorandom number generator |
spdlog | Fast C++ logging library |
stb_image | Header-only public domain library for image loading and saving. |
tinyexr | Tiny OpenEXR image loader/saver library |
tinyobjloader | Tiny but powerful single file wavefront obj loader |
Darts organizes the above libraries and functionality into a few core modules:
Module | Description |
---|---|
Math | Fixed-size vectors/colors, matrices, transforms, rays, orthonormal bases, and other mathy things. |
Utilities | Printing utilities, command-line parsing, and other conveniences. |
Parser | JSON serialization/deserialization, the darts plugin factory, and scene parser. |
Random | Random number generation, generation of points and directions, Monte Carlo utilities. |
Parallel | Constructs to aid task-based parallelism. |
Initially darts does very little beyond accepting some command line parameters and immediately returning. During the course of the term you will extend dart's functionality by implementing various plugins. These include:
Plugin | Description |
---|---|
Surfaces | Geometric surfaces in the scene which can be intersected by rays. |
Materials | BSDFs and phase functions attached to Surfaces to define how they interact with light. |
Textures | Procedural and raster 2D and 3D textures used to drive spatial variation of certain Material parameters. |
Integrators | Algorithms that solve the rendering equation in different ways. |
Samplers | Generate the random number stream used by Integrators to perform Monte Carlo integration. |
Participating media | Define the behavior of light within the volumes between surfaces. |
Next steps
Take a look at our Getting started guide before working through our programming Assignments. You may also optionally want to step through our Discovery cluster tutorial, which shows how to build and run darts on Dartmouth's discovery cluster to render images on many computers at once.