Release Notes for v0.5.3


I provide documentation for the latest official release and intermediate (between releases) updates. The main difference is that one links to source code (for example to the GridDensityMedium struct), whereas the other does not, but is updated more frequently.

Volumetric Data

The biggest change for this release is that we can use volume data, like from a smoke simulation, and render the effect of multiple scattering in participating media.

Smoke Plume

Here is an example using the VolPathIntegrator with different settings for maxdepth (1, 3, and 20):

Using maxdepth 1, 3, and 20

> rs_pbrt -i f15-4a_no_exrs.pbrt
Integrator "volpath"
  "integer maxdepth" [1]
> rs_pbrt -i f15-4b_no_exrs.pbrt
Integrator "volpath"
  "integer maxdepth" [3]
> rs_pbrt -i f15-4c_no_exrs.pbrt
Integrator "volpath"
  "integer maxdepth" [20]

Here three frames from a smoke simulation around an obstacle:

Sequence from a smoke simulation

Implementation Details

The render loop didn't change, currently it can be used for every struct which implements the SamplerIntegrator trait:

  1. AOIntegrator: Ambient Occlusion

  2. DirectLightingIntegrator: Direct Lighting (no Global Illumination)

  3. PathIntegrator: (Uni-directional) Path Tracing (Global Illumination)

  4. VolPathIntegrator: Accounts for scattering and attenuation from participating media as well as scattering from surfaces. The VolPathIntegrator was added by this release.

Remember that there are three more render loops, which are specialized for:

  1. BDPTIntegrator: bi-directional path tracing.

  2. MLTIntegrator: Metropolis Light Transport (MLT).

  3. SPPMIntegrator: Stochastic Progressive Photon Mapping (SPPM).

The volumetric data itself is stored in the new struct GridDensityMedium, especially in the struct field density. I was about to release a new version when I was bothered by the performance (in comparison to C++). Using perf I figured out that changing a couple of lines made a huge difference. Basically I solved the performance problem by creating the density data on API level, so cloning (e.g. in GridDensityMedium::sample(...)) is cheap. The call to self.density.clone() basically only increases the reference count:

pub struct GridDensityMedium {
    pub density: Arc<Vec<Float>>,

The End

I hope I didn't forget anything important. Have fun and enjoy the v0.5.3 release.