Area lights allow for more realistic lighting by simulating light sources with a defined shape and size, resulting in physically correct soft shadows (penumbrae) and natural light distribution. Compared to simply assigning emissive materials to geometry, explicitly implementing area lights allows the integrator to target them with Next Event Estimation (NEE). This significantly reduces noise and improves convergence in scenes dominated by large emissive surfaces.
Sampling Strategy:
Since the framework provided the basic class structure, the primary task was implementing the sampling routines in area.cpp. I chose uniform surface sampling, which involves generating random points on the light's geometry (e.g., spheres or quads).
PDF Conversion & Transforms:
A critical step is converting the uniform probability density function (PDF) from area measure (\(p_A\)) to solid angle measure (\(p_\omega\)). This conversion is necessary for calculating the correct emission contribution and is a prerequisite for Multiple Importance Sampling (MIS).
\[ p_\omega = p_A \frac{d^2}{\cos \theta} \]
Additionally, I modified the Instance class to ensure these PDF values are correctly transformed when the area light is scaled or rotated within the scene.
Bunny with invisible Spherical Area Lights
Bunny with emissive spheres (High Noise)
While the sampling math was straightforward, integrating the lights into the scene graph proved tricky. I initially struggled to make the area lights visible to the camera (rather than just illuminating the scene). I solved this by defining the geometry as a standard instance child of the scene in the XML, and then referencing that instance within the area light definition.
Another challenge was preventing "double counting" of light energy. Initially, I solved this by simply disabling random hits on emissive surfaces, but this was later replaced by a proper Multiple Importance Sampling (MIS) weight calculation.
In path tracing, different sampling strategies work best for different scenarios: Next Event Estimation (NEE) excels at finding small, bright light sources, while BSDF sampling is superior for highly glossy or specular materials. Relying on just one strategy often leads to high variance (noise) or "fireflies." Multiple Importance Sampling (MIS) is a robust technique that combines these strategies, weighing them based on their probability densities. This ensures the renderer automatically favors the most effective technique for every interaction, significantly reducing noise without introducing bias.
Dual PDF Reporting:
MIS requires that every sampling technique be "aware" of the probability of the others. To achieve this, I extended the Light interface with a pdfDirect method,
which calculates the probability (in solid angle measure) of a random ray hitting the light.
Conversely, I refactored the BSDF evaluation and sampling functions to return the PDF of the sampled direction alongside the throughput. This allows the integrator to evaluate the
probability of having found a light source purely via surface scattering.
Power Heuristic:
Inside the main integrator loop, I combined the contributions from NEE and BSDF sampling using the Power Heuristic (with exponent \(\beta=2\)).
\[ w_i = \frac{(p_i)^2}{\sum_{j} (p_j)^2} \]
This heuristic aggressively suppresses low-probability samples (which cause high variance/noise) while preserving energy conservation.
Next Event Estimation only
BSDF sampling only
The most significant challenge was refactoring the sampling logic, particularly within the Principled BSDF, to accurately calculate and return PDFs for the MIS weights. Additionally, I lost significant development time debugging what I believed to be a variance bug. After two days of investigation, it turned out the behavior was correct, though the process did lead to unrelated code optimizations.
Light contribution from emissive volumes relies on BSDF sampled directions to be properly accounted for in the final render. In standard Path Tracing, this often results in high noise because rays must randomly hit the emissive voxels by chance. This feature aims to implement Next Event Estimation (NEE) for heterogeneous volumes, treating them similarly to Area Lights by explicitly sampling the emissive portion of the medium.
Distribution Construction:
I implemented a VolumeLight class which wraps the voxel geometry. During initialization, I flatten the 3D voxel grid and construct a Discrete 1D Distribution based on the luminance of the emission temperature in each voxel.
This allows the sampler to probabilistically select "hot" voxels that contribute most to the lighting.
Sampling & MIS Weighting:
When the integrator performs Next Event Estimation, it selects a voxel from the distribution and generates a random point within it. The emission contribution is calculated by basically treating the voxel as a small area light, accounting for distance attenuation.
Important to mention that the volume transform was accounted for properly in the Instance class.
However, calculating the correct PDF for Multiple Importance Sampling (MIS) is difficult because the point is sampled spatially, but the integrator requires a Solid Angle PDF \(p_\omega\).
To approximate this, I implemented a ray-marching routine.
For every light sample, I march a ray from the shading point to the sampled volume point. This allows me to accumulate the density along the path and estimate a more
accurate weight for the MIS calculation*.
Next Event Estimation Only
Multiple Importance Sampling (Combined)
The primary difficulty was the mathematical conversion between probability domains.
Even with the ray-marching routine, accurately converting the PDF of picking a random point in 3D space \(p_V\) to the Solid Angle PDF (\(p_\omega\)) required a lot of brainstorming.
In hindsight, it also might have been more appropriate to use the volume PDF directly for the MIS calculation and scale the BSDF's solid angle PDF by the transmittance,
rather than attempting to force the volume sample into an angular domain. This misstep likely contributed to the suboptimal energy preservation observed in the renders.