12.6 Infinite Area Lights
Another useful kind of light is the infinite area light—an infinitely far away area light source that surrounds the entire scene. One way to visualize this light is as an enormous sphere that casts light into the scene from every direction. One important use of infinite area lights is for environment lighting, where an image that represents illumination in an environment is used to illuminate synthetic objects as if they were in that environment. Figure 12.19 compares illuminating a car model with a standard area light to illuminating it with a few environment maps that simulate illumination from the sky at a few different times of day. The increase in realism is striking. The InfiniteAreaLight class is implemented in lights/infinite.h and lights/infinite.cpp.
A widely used representation for light for this application is the latitude–longitude radiance map. (This representation is also known as the equirectangular projection.) The EnvironmentCamera can be used to create image maps for the light, or see the “Further Reading” section for information about techniques for capturing this lighting data from real-world environments. Figure 12.20) shows the radiance maps used in Figure 12.19.
Like the other lights, the InfiniteAreaLight takes a transformation matrix; here, its use is to orient the image map. It then uses spherical coordinates to map from directions on the sphere to directions, and from there to texture coordinates. The provided transformation thus determines which direction is “up.”
The constructor loads the image data from the disk and creates a MIPMap to store it. The fragment that loads the data, <<Read texel data from texmap and initialize Lmap>>, is straightforward and won’t be included here. The other code fragment in the constructor, <<Initialize sampling PDFs for infinite area light>>, is related to Monte Carlo sampling of InfiniteAreaLights and will be defined later, in Section 14.2.4.
As with DistantLights, because the light is defined as being infinitely far away, the MediumInterface for an infinite area light must have nullptr values for its Medium *s, corresponding to a vacuum.
Like DistantLights, InfiniteAreaLights also need the scene bounds; here again, the Preprocess() method finds the scene bounds after all of the scene geometry has been created.
Because InfiniteAreaLights cast light from all directions, it’s also necessary to use Monte Carlo integration to sample their illumination. Therefore, the InfiniteAreaLight::Sample_Li() method will be defined in Section 14.2.
Like directional lights, the total power from the infinite area light is related to the surface area of the scene. Like many other lights in this chapter, the power computed here is approximate; here, all texels are given equal weight, which ignores the fact that with an equirectangular projection, the differential solid angle subtended by each pixel varies with its value (Section 14.2.4).
Because infinite area lights need to be able to contribute radiance to rays that don’t hit any geometry in the scene, we’ll add a method to the base Light class that returns emitted radiance due to that light along a ray that escapes the scene bounds. (The default implementation for other lights returns no radiance.) It is the responsibility of the integrators to call this method for these rays.