Source code of the talk "Practical Multiple-Scattering Sheen Using Linearly Transformed Cosines" by Tizian Zeltner, Brent Burley, and Matt Jen-Yuan Chiang presented at SIGGRAPH 2022.
-
The
pbrt-v3
directory contains our reference implementation of the final sheen BRDF together with additional baselines and prior work that we compare against in the supplementary material. -
All code necessary to reproduce the LTC fitting is located in the
fitting
directory.
We introduce a new volumetric sheen BRDF that approximates scattering observed in surfaces covered with normally-oriented fibers. The implementation is based on a linearly transformed cosine (LTC) lobe [Heitz et al. 2016]. To be precise, our cosine-weighted BRDF is
where
Their values are fit to a reference BRDF for a regular grid of 32 inputs for both
In terms of reference BRDFs we use two versions in this codebase (which are both impractical to use directly in a renderer):
-
The volumetric layer with a fiber-like SGGX phase function discussed in the talk abstract, where the cross section parameter
$\sigma \text{ }\in\text{ } [0, 1]$ is mapped to the roughness as$\alpha = \sqrt{\sigma}$ . Importantly, this includes multiple-scattering which requires a costly stochastic evaluation via random walks. Further, we are only interested in its reflected component which is poorly importance sampled in some configurations and thus can have unacceptably high variance. (See code) -
An analytic approximation of the above that is very cheap to evaluate. However it cannot directly be importance sampled which also leads to variance in practice. (See code)
By fitting suitable LTC parameters we can sidestep all of these issues and arrive at BRDFs with efficient evaluation and perfect cosine-weighted importance sampling. Because the cosine is baked in (for sampling efficiency), the resulting BRDF is only approximately reciprocal, which we did not find problematic in practice.
We provide precomputed coefficient tables for both versions. They are also visualized below.
Fitted BRDF | NumPy array | C++ array |
---|---|---|
SGGX volume | ltc_table_sheen_volume.npy |
ltc_table_sheen_volume.cpp |
Approximation | ltc_table_sheen_approx.npy |
ltc_table_sheen_approx.cpp |
Note how the left-most parts of the tables for version (1) are not smooth. The stochastically evaluated BRDF is particularly noisy in those
Version (2) produces lookup tables that are smooth in all regions, but at the cost of slightly higher approximation error compared to the original SGGX volume layer reference.