The simplifying assumption that had been made upto this point in our BSDF materials was that the incoming and outcoming directions came from the same point. In reality for many materials, light penetrates the surface, scatters internally, and exits at a different point. This phenomenon is known as subsurface scattering and is crucial for rendering realistic materials like skin, marble, and wax. To achieve this effect, we need a BSSRDF (bidirectional subsurface reflectance distribution function) instead of a simple BSDF. \[ L_o = \int_A \int_{\Omega} BSSRDF(p_o, \omega_o, p_i, \omega_i) L_i(p_i, \omega_i) | \cos \theta_i | d\omega_i dA \] We thus integrate both over the directions and the areas.
Architecture & Integration:
The existing framework was designed strictly for BSDFs (local scattering), making it incompatible with BSSRDFs which require integrating over both surface area and direction.
To solve this, I implemented a new BSSRDF class that separates these integrals. The class handles the spatial component—sampling a new point on the surface based on a channel-wise radius parameter—while owning an internal BSDF instance to handle the directional hemisphere integration at that new point.
For the diffusion profile itself, I utilized the Christensen-Burley model. This offers better performance and visual quality compared to the standard dipole models often found in resources like PBRT.
Path Tracer Modifications:
Integrating this required updates to the scene parser and, most importantly, mispathtracer.cpp. The integrator was modified to detect BSSRDF materials and perform the split integration step—essentially "submerging" the ray into the surface and popping it out at a new location.
Following optimizations suggested in this blog post, I limited the effect to a single SSS bounce per path. This significantly reduces computational complexity while maintaining visual fidelity.
To support this efficiently, I included a shortcut computation within the BSSRDF class: when the scattering radius is zero, it reverts to standard BSDF behavior, avoiding unnecessary area sampling overhead.
Subsurface Scattering with No Radius
Diffuse BSDF
Diffuse BSDF
Realistically, the entire implementation process was quite challenging, as it required a deep understanding of both the theoretical aspects of subsurface scattering and the practical considerations of implementing it within the existing lightwave framework.
Furthermore, the PBRT book itself actually implements a tabulated BSSRDF, utilizing the photon beam diffusion (PBD) model. This approach, while accurate, is quite complex and time-consuming to implement. Fortunately, the blog post mentioned earlier suggested utilizing the Christensen-Burley model, which is not only simpler but also produces more accurate results (reason being the other simplifying assumptions made for our BSSDRF models, including PBD, affect the overall accuracy more than the choice of BSSRDF model itself).
A bug I encountered was actually due to the geometric intersection process. Initially, I had inadvertently mixed both geometric and shading frames during the area sampling process, producing nasty artifacts in the renders. I even tried asking on the forum, but as luck would have it, I figured out the solution right after posting the question, leading me to promptly delete it.
While the standard Principled BSDF covers many hard-surface materials, it lacks the nuance required for complex organic and textile surfaces. To address this, I extended the material model with features inspired by the Blender and Disney implementations:
Theoretical Basis:
The implementation relies heavily on the physically based shading models described in Joe Schutte's Disney BSDF blog post. I extended the existing Principled class to support these new parameters and updated the internal logic to mix these lobes correctly.
Lobe Composition:
Material Shape - Diffuse Roughness set to 1.0 (Flatter look)
Material Shape - Diffuse Roughness set to 0.0
Reference: Material Shape with Standard Lambertian Diffuse
Sphere with Sheen (Denim Textile)
Sphere with Thin-walled Translucency (Light source placed inside)
The primary challenge was architectural: deciding which parts of the comprehensive Disney/Blender model were strictly necessary for my goals (textiles and thin geometry) versus what was effectively bloat.
I encountered a subtle shading bug where back-facing surfaces appeared incorrectly darkened or produced invalid values. I eventually traced this to my evaluation function using the raw cosine term rather than the absolute value (absCosTheta). This caused the dot products for backward-facing normals to become negative, breaking the energy calculations.