View on GitHub


A (not too) small physically based renderer

Download this project as a .zip file Download this project as a tar.gz file


SmallVCM is a small physically based renderer that implements the vertex connection and merging algorithm described in the paper

Light Transport Simulation with Vertex Connection and Merging
Iliyan Georgiev, Jaroslav Křivánek, Tomáš Davidovič, and Philipp Slusallek
ACM Transactions on Graphics 31(6) (SIGGRAPH Asia 2012) a

as well as a number of other algorithms, notably including progressive photon mapping, (progressive) bidirectional photon mapping, and bidirectional path tracing. The code compiles to a command line program that can render images of a number of predefined scenes using the provided algorithms.

Report (10 sec), Report (60 sec)
SmallVCM can generate HTML reports that compare 6 global illumination algorithms on 4 Cornell box variants. We have put two such reports on this web site for demonstration. a


With that out of the way, let's go over the usual stuff.

Compilation and Installation

Synopsis: Compile smallvcm.cxx with OpenMP. If you don't have C++11 support, define LEGACY_RNG (automatic for VS2008, found in rng.hxx).

The whole program consists of one C++ source file and a multiple header files. It was developed in VS2010, however we did some limited testing on Linux, and the provided Makefile works for g++ 4.4 and 4.6.3 at least.

The major hurdle can come from the fact that the C++11 library is used, but an alternative random number generator is also provided (make old_rng on Linux). The code expects OpenMP is available, but getting rid of that is very straightforward (simply comment out the few #pragma omp directives in the code).

Other than that, there are no dependencies, so simply compile smallvcm.cxx.


Quick start: Run smallvcm --report -t 10. In about 5-6 minutes it will generate an index.html file that compares 7 different algorithms on 4 different Cornell box variants (listed below).

The features and settings of the program can be explored by running smallvcm --help, which outputs the following information:

Usage: smallvcm [ -s <scene_id> | -a <algorithm> |
           -t <time> | -i <iteration> | -o <output_name> | --report ]

    -s  Selects the scene (default 0):
          0    glossy small spheres + sun (directional)
          1    glossy large mirror sphere + ceiling (area)
          2    glossy small spheres + point
          3    glossy small spheres + background (env. lighting)
    -a  Selects the rendering algorithm (default vcm):
          el   eye light
          pt   path tracing
          lt   light tracing
          ppm  progressive photon mapping
          bpm  bidirectional photon mapping
          bpt  bidirectional path tracing
          vcm  vertex connection and merging
    -t  Number of seconds to run the algorithm
    -i  Number of iterations to run the algorithm (default 1)
    -o  User specified output name, with extension .bmp or .hdr (default .bmp)
        Renders all scenes using all algorithms and generates an index.html file
        that displays all images. Obeys the -t and -i options, ignores the rest.
        Recommended usage: --report -i 1   (fastest preview)
        Recommended usage: --report -t 10  (takes 5.5 min)
        Recommended usage: --report -t 60  (takes 30 min)

    Note: Time `-t` takes precedence over iterations `-i` if both are defined

glossy applies to the floor of the Cornell box.
small spheres variants have one mirror and one glass spheres in the box.

The program can run in two modes:

  1. If --report is not set, a single image of the specified scene will be rendered using the specified algorithm. If no option is specified, the output is a 512x512 image of scene 0 is rendered using vertex connection and merging with 1 iteration.
  2. Setting the --report option renders all scenes using all algorithms, obeying the (optional) number of iterations and/or maximum runtime for each scene-algorithm configuration, ignoring the other options.

All default settings are set in the ParseCommandline function in config.hxx. Some settings have no command line switch, but can be changed in the code:

mNumThreads Number of rendering threads (default 0, means 1 thread/core)
mBaseSeed Seed for random number generators (default 1234)
mMinPathLength Minimal path length (i.e. number of segments) (default 0)
mMaxPathLength Maximal path length (i.e. number of segments) (default 10)
mResolution Image resolution (default 512x512)
mRadiusFactor Scene diameter fraction for the merging radius (default 0.003)
mRadiusAlpha Merging radius reduction parameter (default 0.75)

VertexCM Renderer

The VertexCM renderer implements a number of algorithms that share almost identical code paths. The main differences between the algorithms lie in the multiple importance sampling (MIS) weight computation, as well as shortcuts through unused code. In order to make the understanding of the code easier, below we describe how the VertexCM renderer operates. On a high level, it runs in three stages:

  1. Light sub-path tracing (ppm, bpm, bpt, vcm)
  2. Range search hash grid construction over light vertices (ppm, bpm, vcm)
  3. Camera sub-path tracing (all but lt)

PathVertex (also PathElement variant and typedefs CameraVertex and LightVertex) is the basic structure describing the state of a random walk. The only unusual members are dVCM, dVC, dVM, which are used for iterative MIS weight computation:

dVCM used for both connections (bpt, vcm) and merging (bpm, vcm)
dVC used for connections (bpt, vcm)
dVM used for merging (bpm, vcm)

Note: All bidirectional algorithms sample the same number of light and camera sub-paths per iteration, which is the number of pixels in the image.

Features and Limitations

The renderer was originally intended to be a compact reference implementation, akin to SmallPT, however it grew over time. Here is a list of the features and the limitations of the framework:

Infrastructural features:

Rendering features: