Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

In Arnold 5.0 surfaces and volume shaders return closures rather than final colors. Closures describe the way surfaces and volumes scatter light, leaving the lights loops and integration to Arnold. This approach makes more optimizations and better rendering algorithms possible.

Types

BSDF and BSSRDF Closures

BSDF and BSSRDF closures define how light scatters on and below surfaces.

...

Code Block
languagecpp
titleBSSRDF
 // OSL
result = weight * empirical_bssrdf(mean_free_path, albedo);

// C++
sg->out.CLOSURE() = AiClosureEmpiricalBSSRDF(sg, weight, mean_free_path, albedo);

Refraction BSDFs and Absorption

For refraction, the BSDF takes an interior closure list parameter that defines the interior of the object. This can be used to model volume absorption or scattering inside glass for example.

Code Block
languagecpp
titleBSSRDF
// C++
AtClosureList interior = AiClosureVolumeAbsorption(sg, absorption_coefficient);
sg->out.CLOSURE() = AiMicrofacetRefractionBSDF(sg, ..., interior);

Emission Closure

The emission closure is used to emit light from surfaces.

Code Block
languagecpp
titleEmission
 // OSL
result = intensity * color * emission();

// C++
sg->out.CLOSURE() = AiClosureEmission(sg, intensity * color);

Transparent and Matte Closures

Surfaces are opaque by default, and the transparent and matte closures can be used to make them transparent or to affect the alpha channel. When making a surface transparent or matte, other surface closures should have their weight reduced accordingly, so that the total weight of all closures does not exceed 1 and energy is conserved. Mixing with other closures can be done as follows:

...

Code Block
languagecpp
titleStochastic transparency
// handle opacity
AtRGB opacity = AiShaderGlobalsStochasticOpacity(sg, AiShaderEvalParamOpacity(p_opacity));
if (opacity != AI_RGB_WHITE)
{
   sg->out.CLOSURE() = AiClosureTransparent(sg, AI_RGB_WHITE - opacity);
   // early out for nearly fully transparent objects
   if (AiAll(opacity < AI_OPACITY_EPSILON))
      return;
}

// early out for shadow rays
if (sg->Rt & AI_RAY_SHADOW)
   return;
 
// create shader closures
AtClosureList closures = ...;

// write closures
if (opacity != AI_RGB_WHITE)
{
   closures *= opacity;
   sg->out.CLOSURE().add(closures);
}
else
{
   sg->out.CLOSURE() = closures;
}

Volume Closures

The weights of volume closures are absorption, scattering and volume coefficients, with higher values resulting in denser volumes. Shadow rays only need absorption, and so may skip computation of scattering and emission and avoid evaluating any linked parameters needed for them.

...

AOVs

Shaders using closures can not cannot write lighting to AOVs themselves, rather Light Path Expression AOVs can be used.

...