Page History
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 | ||||
---|---|---|---|---|
| ||||
// 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 | ||||
---|---|---|---|---|
| ||||
// 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 | ||||
---|---|---|---|---|
| ||||
// 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 | ||||
---|---|---|---|---|
| ||||
// 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.
...