Accurate representations of real-world materials are a crucial prerequisite for realistic image synthesis. This project focuses on modeling cloth appearance based on light scattering from individual threads. Making use of reflectance acquisition techniques, we have studied a variety of threads extracted from real-world fabrics.
A Practical Microcylinder Appearance Model for Cloth Rendering
Iman Sadeghi, Oleg Bisker, Joachim De Deken, Henrik Wann Jensen
ACM Transactions on Graphics (SIGGRAPH 2013)
The cloth BRDF sampling formulation described in the Siggraph paper is the vanilla flavor of a multitude of possible approaches. It uniformly picks samples from each of the orthogonal tangent curves and computes a weighted average based on relative visibility. In practice, this can be quite costly especially for curves with few flat sections.
An alternative sampling scheme is to focus the samples based on where the reweighting function has the highest values. In an MC-style renderer this gives us an instant preview and reduced workload by not wasting samples on portions of the tangent curve which are self-occluded or minimally contributing. The code implements a very basic version of this concept to reduce excess thread BSDF evaluation. In the future, we plan to extend the importance sampling to take into account the shadowing/masking and possibly the actual scattering lobes.
Accurately computing the angles in the right ranges is step one. By projecting the eye/light vectors into a tangent-space we can easily compute the three angle quantities used in the paper: \(\theta, \phi, \psi\). There are alternative derivations for the angles that avoid transcendental functions, however they are less concise and easier to get wrong.
Relevant Code - [View Shader Source] -
Params: tangent basis vectors
Returns: tangent frame Vec3f(\(\theta, \phi, \psi\)) angles used in BSDF:
Vec3f getTangentBasisAngles(n,t, t’, w)
Scattering contribution from a single thread sample.
Params: tangent basis angles and thread attributes
Returns: thread scattering Vec2f(volume scatter, surface reflect):
Vec2f threadBSDF(\(\theta_i, \phi_i, \theta_r, \phi_r\), lobeWidth, ior, kd)
Thread contribution to cloth by applying shadowing/masking/reweighting to single tangent curve sample.
Params: tangent curve sample basis, and incident and outgoing directions
Returns: thread scattering Vec2f(weavevol. scatter, weavesurf. reflect):
Vec2f weaveBRDFSample(n, t, t’, \(\omega_i, \omega_o\), thread, ...)
Weave BRDF by combining contributions from tilted tangent curve samples specified in the weave pattern.
Params: surface tangent basis, and incident and outgoing directions
Returns: weave surface reflectionCol3f(RGB color):
Col3f weaveBRDF(n, t, t’, \(\omega_i, \omega_o\))