Home

Awesome

Build Status Documentation Status

blazeRT

  1. Introduction
    1. Contributing
    2. Versions
  2. Features
  3. Installation
    1. Dependencies
    2. Clone the repository
    3. Build and Test
    4. Configuration
  4. Usage
    1. Examples
    2. Minimal Examples
    3. Notes
  5. Benchmarks
  6. License

Introduction

blazeRT is a double precision ray tracer for scientific or engineering applications derived from nanoRT using blaze datatypes and written in modern C++17. blazeRTs scene interface is similar to embree and intents to be a minimal effort (nearly plugin-) replacement. blazeRT should work on any system and architecture for which a recent (C++17 compatible) compiler is available.

We aim at providing a simple and unambiguous high-level API for the ray-traversal. We do not aim at providing backwards-compatibility (especially to older C++ standards).

blazeRT makes use of the the blaze linear algebra library for its vector types. Because we rely on a well-tested and well-optimized linear algebra library (instead of using our own vector types), blazeRT can focus on the actual ray tracing algorithms. Furthermore, using types from a linear algebra library is advantageous for the subsequent development of scientific application where the vector types are needed again. blazeRT should work with any library providing these vector types as long as certain criteria are met (a minimal set of operation on these vector types).

blazeRT works with triangular meshes and simple primitives, but it is easy to extend blazeRT to work on polygons or more complex primitives. A template for user-defined geometries can be found here. If you implement new geometries, we are more than happy to receive a pull request from you to include it in blazeRT.

blazeRT is tested using unit tests (whose number will increase as development progresses) as well as by comparison of rendering results to reference images. Currently the unit tests cover roughly 90% of files and 69% of lines, but in the tests we try to catch as many (fringe-) cases as possible. We try to ensure high code quality and a reproducible build experience via continuous integration. During the CI process we build the examples and the tests, which need to run successfully in order for the CI to pass. Currently, blazeRT is CI-tested on Ubuntu 18.04 and macOS with gcc and clang.

image

(Rendered using the path_tracer example adapted from nanoRT and originally contributed by daseyb)

Contributing

We appreciate all contributions from issues to pull requests.

For contributing, please read the contribution guide.

Versions

The releases are based on the master branch. The release-version is tagged and follows the scheme Year.Quarter.Revision.

Features

Installation

Installation and build are tested on linux (e.g. ubuntu bionic, arch linux) and macOS. Before starting the build process please ensure all dependencies are properly installed and available to the project.

Dependencies

Clone the repository

Clone the repository with the following command: git clone https://github.com/cstatz/blazert.git

For the tests and the benchmarks the submodules must be cloned as well:

git submodule init
git submodule update 

This will pull doctest, nanoRT and madmann91/bvh as submodules.

Build and test

For windows read this: building on windows

This is a header-only library. No need to build anything. Just drop it in your source directory and off you go. The build step is solely for the examples, tests and the benchmark.

We strictly recommend an out-of-source build in a separate directory (here for simplicity build) Starting in the source directory to project is build from the commandline as follows:

mkdir build
cd build 
ccmake ../  # create cache and configuration
cmake --build .
cmake --build . -- install  # If package needs to be installed 
ctest  # Runs the tests

For maximum performance, we recommend building with gcc which results in a 15% to 20% better performance compared to clang (on linux and macOS). The provided benchmarks might be used to tune the compilation flags for your specific system and architecture.

A word of caution: blazeRT will compile and work with compiler optimizations enabled (up to -O3), but needs infinite-math. If your application needs fast-math, ensure that the blazeRT code path is compiled with -fno-finite-math-only (in case of clang). In terms of performance, in its current form there is no major runtime difference between compilation with -O2 and -O3.

Configuration

The easiest way to set the configuration variables is by using ccmake or pass the variables via cmake ../ -D<VARIABLE>:<TYPE>=value.

Usage

To get familiar with the usage of blazeRT, look at the provided examples and test cases. To get started quickly, checkout the minimal examples below. The full documentation includeing the API reference is available here.

Either prim-references, -indices or primitives are stored in the bvh-nodes. Which case is implemented depends on the prim-collection.

Examples

Minimal Example

Example for using blazeRT can be found the the examples subdirectory.

To give you an impression of the High-Level API (adapted from examples/scene_primitives):

// snip 8<
  
  /// Create the scene and add some primitive collections:
  blazert::Scene<ft> scene;
  scene.add_cylinders(*centers, *semi_axes_a, *semi_axes_b, *heights, *rotations);
  ///scene.add_spheres( ... );
  ///scene.add_triangles( ... );
  
  /// Commit and build the scene
  scene.commit();
  
  /// Iterate over the ray directions:
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {

      const blazert::Ray<ft> ray{{0.0, 5.0, 20.0}, 
      		                    {static_cast<ft>((x / ft(width)) - 0.5),
                                 static_cast<ft>((y / ft(height)) - 0.5), 
                                 static_cast<ft>(-1.)}};
      blazert::RayHit<ft> rayhit;
      
      if (intersect1(scene, ray, rayhit)) { 
        /// Do something useful ...
      }
    }
  }

// >8 snip

Notes

Benchmarks

We have included benchmarks comparing blazeRT to nanoRT, embree and madmann91/bvh for bvh build and traversal. The benchmark scene is a (triangle-) meshed sphere which which can be refined by sub-division. There are two traversal cases:

The benchmarks are run for the most recent (git-) revisions of the compared ray tracing libraries.

Please take the results with a grain of salt. The measured timings heavily depend on the chosen compiler, compiler version, level of optimization, operating system, system architecture, and the way the system is used otherwise (e.g. do multiple users have concurrent access to the system). We cannot guarantee that the optimal configuration (or even api) is chosen for all benchmarked libraries. Regarding embree: we're comparing traversal or intersection routines that are similar in behaviour. That means, for embree the benchmarks are performes with single ray traversal (rtcIntersect1). This is not optimal and embree is way more powerful (leveraging all the vectorization goodness) using the streaming api (or calls to rtcIntersectN).

The provided results were obtained using the following configuration:

The following plots show the benchmark results for the bvh build and the traversal for a realistic rendering case (not all rays hit) and for a realistic scientific rendering case (all rays hit).

Benchmark BVH build Benchmark BVH traversal rendering Benchmark BVH traversal scientific

License

blazeRT is licensed under the new BSD (3-clause) license. blazeRT is based on and inspired by nanoRT.h which is licensed under MIT-License. For comparability, nanoRTs path_tracer and madman91/bvhs benchmark have been adapted to blazeRT to generate a baseline for the tests and benchmarks.

We decided to not extend nanoRT due to the intrusive nature of the changes that came with the introduction of the blaze datatypes. Another reason was the possibility for an enhanced maintainability if the code is not kept (and developed) in a single-header library.

The examples are built around third-party libraries (e.g. tiny_obj_loader and stb_image_write) which adhere to their own respective licenses (found in the included files).

The rendering examples are taken from the nanoRT and bvh repos and serve as a baseline. The Lucy model included in the demo scene is taken from the Stanford 3D Scanning Repository: http://graphics.stanford.edu/data/3Dscanrep/