Area Light Sampling

In our previous version of the renderer we already supported emissive shapes. These emissive shapes can be used to simulate area lights. However, these emissive shapes are treated like any other shape, which means that their contribution to the lighting is only used when we hit them randomly. In contrast, point lights and area lights are already sampled directly, meaning we pick a random light source and compute the contribution of it to some hitpoint in the scene. With area light sources we now do essentially the same to reduce noise.

The idea is to wrap our emmisive shape as an area light. For point lights and directional light checking for occlusion is straight forward, but for area lights occlusion depends on where the light ray originates from on the surface. Fixing one point as an origin of every ray coming from the area light would essentially reduce the light to point light. It follows that we need to sample the area of the object to get a random point from its surface. This is supported for rectangles and spheres here, as in these cases we can easily get points sampled from a uniform distribution over the surface area. We then use that point to compute occlusion.

To implement this feature in lightwaves framework we simply needed to extend the Light class with an AreaLight class. There we get an instance as input (which should be emissive). We can override the sampleDirect method and where we first sample the instance to get a random hitpoint on its surface, then evaluate the emission and then return this light accounting for energy loss over distance.

The hardest part in the implementation is actually understanding the dataflow of the framework, but it is quiet practical for implementation.

AreaLight Off AreaLight On

The left side is with the emissive shapes that can be intersected, so they are visibly, while the right side has the same emissive shapes but they are wrapped as an area light (which cannot be intersected, so it is invisible).