System Overview

Geometric primitives

Relevant code:

  • src/core/primitives/Primitive.hpp
  • src/core/primitives/Primitive.cpp
  • src/core/primitives/Mesh.hpp
  • src/core/primitives/Mesh.cpp
  • src/core/primitives/Quad.hpp
  • src/core/primitives/Sphere.hpp
  • src/core/primitives/Spotlight.hpp
  • src/core/primitives/InfiniteSphere.hpp
  • src/core/primitives/InfiniteSphereCap.hpp

Currently, the renderer supports 6 different geometric primitives. The most general and the most useful primitive is the triangle mesh, which is what you would usually use to build your scene. There are a number of other analytic geometric shapes, mainly for use as light sources. Although triangle meshes can be used as light sources too, the corresponding analytic counterpart is usually more efficient and generates a better sampling distribution.

Any primitive can be turned into a light source by giving it non-zero emission. In fact, all primitives support textured emission, where the emission value is provided by a bitmap or procedural texture. For that reason, all primitives support generating inbound (path tracing) and outbound (light tracing) directions for light sampling and can compute the pdf of generating a given direction in the solid angle measure.

For textured emission, some primitives are also capable of mapping UV coordinates to points on the surface and computing the Jacobian of that mapping; this way, a point on the emission texture can be sampled and turned into a point on the surface. For primitives that don't support this (i.e. triangle meshes), the surface will just be sampled uniformly, even with textured emission. This is not optimal, but better than not sampling the emitter at all.

The complete list of supported primitives is given below:

  • Triangle mesh: The classic. Supports smooth vertex normals, UV coordinates, light sampling and UV tangent space.
  • Textured triangle mesh primitive

    Textured triangle mesh primitive

  • Analytic sphere: Useful for light sources and refractive balls
  • Textured sphere primitive

    Textured sphere primitive

  • Analytic quadrilateral: Useful for light sources
  • Textured quadrilateral primitive

    Textured quadrilateral primitive

  • Analytic disk: Useful for light sources. Also allows to constrain the emission angle to act as a spot light
  • Textured disk primitive

    Textured disk primitive

  • Infinite sphere: An infinitely distant sphere. This is what you would use for environment maps by giving it an emissive texture
  • Infinite sphere primitive with textured emission

    Infinite sphere primitive with textured emission

  • Infinite spherical cap: An infinitely distant spherical cap. This is useful for finite directional emitters, e.g. the sun
  • Infinite spherical cap primitive lighting a ground plane

    Infinite spherical cap primitive lighting a ground plane

BSDF overview

Relevant code:

  • src/core/bsdfs/Bsdf.hpp
  • src/core/bsdfs/Bsdf.cpp

The renderer supports various BSDFs to mimic different materials. BSDFs typically provide one or several parameters to control the underlying model, which can be set through the JSON file. Many BSDFs in the renderer also support textured parameters, meaning that the scalar or vector value in the JSON can be replaced by a path to an image or a procedural texture. Examples of textured BSDF parameters are given in the feature sections, but this list is by far not exhaustive. Just try it out and see for yourself!

To facilitate material testing and comparison, there is a standard material test scene that comes with the renderer, featuring a simple backdrop, an environment map and a "material test ball" in the style of Mitsuba and other renderers. The test scene is shown below for a textured lambertian BSDF:

Material test scene

The Tungsten material test scene

To decrease code duplication and improve consistency across BSDFs, there is a set of standard parameters that are supported by all BSDFs. These are as follows:

  • Bump map: Adds small scale detail to the shading normals. See the bump map section for more info
  • Alpha: Controls the opacity of the surface, which is useful for masking (in foliage, for example) or not completely opaque surfaces such as thin plastic foil. An example of binary masking for a lambert BSDF is shown below:
  • An example of alpha masking

    Textured transparency

  • Surface albedo: Controls the diffuse reflectance of the surface, often perceived as the "color" of a material. Note that this parameter is ignored for dielectrics to remain physical.

Texture overview

Relevant code:

  • src/core/materials/Texture.hpp
  • src/core/materials/BitmapTexture.hpp
  • src/core/materials/CheckerTexture.hpp
  • src/core/materials/DiskTexture.hpp
  • src/core/materials/BladeTexture.hpp

For the renderer, I implemented a texture system that can combine constant values, bitmap textures and procedural textures in the same framework. Anywhere a texture parameter is valid in the JSON, a constant value (either scalar of vector) can be used instead. In a similar vein, changing a constant parameter to use a texture instead is as simple as using the path to the image file as the parameter. For procedural textures, a texture object can be instantiated in the parameter.

Since textures are used, among others, to specify emission and apertures, all textures in the renderer, including procedural textures, have to be perfectly samplable according to the texel luminance. When turning a texture into a samplable object, the caller can also give a hint as to the Jacobian of the UV mapping. This is used, for example, in environment maps, where the environment primitive will hint that it's using a spherical mapping, so that the bitmap texture can warp the sample distribution according to the sine of the inclination angle.

Below is a list of the implemented textures, including their sampling distributions:

Bitmap texture

Various LDR formats such as JPG, PNG, TGA, BMP, GIF as well as HDR textures in PFM format are supported.

HDR Texture

HDR Texture

HDR Texture

Sample distribution on HDR texture

Checker texture

Useful for testing. The number of squares in the U- and V- direction can be controlled individually and the on- and off- color of the squares can also be changed.

Checker Texture

Procedural checker texture

Checker Texture

Sample distribution on procedural checker texture

Disk texture

This texture is mostly intended for apertures. There are no parameters.

Disk Texture

Procedural disk texture

Disk Texture

Sample distribution on procedural disk texture

Blade texture

This texture is mostly intended for apertures. The number of blades as well as the rotation of the texture can be controlled.

Blade Texture

Procedural blade texture

Blade Texture

Sample distribution on procedural blade texture