Release Notes for v0.5.0


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 TabulatedBssrdf struct), whereas the other does not, but is updated more frequently.

Subsurface Scattering (SSS)

The biggest changes for this release is that we support Subsurface Scattering (SSS) now. Here an example scene (or a whole repository full of them):

SSS Dragon


There are two related issues about the topic (SSS):

  1. Implement SubsurfaceMaterial (closed): That was the main task for this release, to implement everything related to SubsurfaceMaterial.

  2. Issue 85 (open): There was one functions which hosted a loop which was executed in parallel in the original C++ code. That remains to be done in future releases.

New modules

If you are interested in the details about new modules, structs, traits, and functions added by this release, here are some links to the documentation:

  1. The module subsurface contains the struct SubsurfaceMaterial which implements the functions defined by the Material trait.

  2. The module bssrdf contains three structs, two traits, and a couple of functions, all related to a bidirectional scattering surface reflectance distribution function (BSSRDF), which returns the exitant radiance at a point on a surface given the incident differential irradiance at another point.

Minor changes

All current implementors of the Material trait (except MixMaterial) provide a create function with the following signature:

pub fn create(mp: &mut TextureParams) -> Arc<Material + Send + Sync>

This differs from the C++ implementation, which has a function for each material, which returns a pointer to the concrete class:

> rg -tcpp "Create[a-zA-Z]*Material"
65:MatteMaterial *CreateMatteMaterial(const TextureParams &mp);
224:FourierMaterial *CreateFourierMaterial(const TextureParams &mp) {

209:        std::shared_ptr<Material> mtl(CreateMatteMaterial(tp));
547:        material = CreateMatteMaterial(mp);
549:        material = CreatePlasticMaterial(mp);
551:        material = CreateTranslucentMaterial(mp);
553:        material = CreateGlassMaterial(mp);
555:        material = CreateMirrorMaterial(mp);
557:        material = CreateHairMaterial(mp);
559:        material = CreateDisneyMaterial(mp);
580:        material = CreateMixMaterial(mp, mat1, mat2);
582:        material = CreateMetalMaterial(mp);
584:        material = CreateSubstrateMaterial(mp);
586:        material = CreateUberMaterial(mp);
588:        material = CreateSubsurfaceMaterial(mp);
590:        material = CreateKdSubsurfaceMaterial(mp);
592:        material = CreateFourierMaterial(mp);
595:        material = CreateMatteMaterial(mp);

For all vector/normal structs you should be able to index into their member variables:

> rg -trust "Index" src/core/
185:use std::ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub};
227:impl<T> Index<u8> for Vector2<T> {
238:impl<T> IndexMut<u8> for Vector2<T> {
417:impl<T> Index<u8> for Vector3<T> {
429:impl<T> IndexMut<u8> for Vector3<T> {
698:impl<T> Index<u8> for Point2<T> {
709:impl<T> IndexMut<u8> for Point2<T> {
950:impl<T> Index<u8> for Point3<T> {
962:impl<T> IndexMut<u8> for Point3<T> {
1210:impl<T> Index<u8> for Normal3<T> {
1222:impl<T> IndexMut<u8> for Normal3<T> {
1661:impl<T> Index<u8> for Bounds3<T> {

So it should be possible to e.g. access the three coordinates of a Normal3 like this:

    let float_normal = Normal3 {
        x: 0.0,
        y: 1.0,
        z: 2.0,
    println!("Normal3 {{ x: {}, y: {}, z: {} }}",
             float_normal[0], float_normal[1], float_normal[2]);
    // or
    println!("Normal3 {{ x: {}, y: {}, z: {} }}",
             float_normal.x, float_normal.y, float_normal.z);
    // or (simply)
    println!("{:?}", float_normal);

The struct SurfaceInteraction has a field with an optional TabulatedBssrdf:

#[derive(Default, Clone)]
pub struct SurfaceInteraction<'p, 's> {
    pub bssrdf: Option<Arc<TabulatedBssrdf>>,

The struct InteractionCommon has a new method spawn_ray_to_pnt(...).

There is a new function integrate_catmull_rom(...).

The Material::compute_scattering_functions(...) trait function has a new material parameter (use None in case its not needed).

Only the PathIntegrator can render subsurface scattering (this is true for the C++ version as well). The added functionality is found in PathIntegrator::li(...).

The End

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