In Praxis: Lighting
The previous installment of In Praxis talked about how surfaces react to light. This post gives an overview of where that light comes from.
We have a single primary light source: the sun. As is common in real-time graphics, it is modeled as a directional light. Apart from any dynamic local light sources in the world, all light is somehow derived from the sun. For the shadowing of the sun we use fairly standard stable cascaded shadow maps combined with jittered sampling for smooth shadow edges. A neat little detail is increasing the shadow filter radius when the sun is partially occluded by clouds, giving a more diffuse look.
An important secondary light source is the sky. Its color and intensity directly derive from the color and intensity of the sun, as well as the scattering properties of the atmosphere. We use the approach presented in  to inexpensively compute the amount of light scattered by the atmosphere into the camera. In addition to just a clear sky we also have a dynamically varying cloud cover. Both of these elements are rendered dynamically into an environment map, which is then projected into spherical harmonics. This ends up as the ambient light that affects the diffuse shading of surfaces. The result is that the ambient lighting matches the sky at different times of day and in different weather conditions. We also render another environment map with the sky as well as black silhouettes of large objects and use it for the glossy specular reflections on surfaces, as described in the previous post.
Directional ambient lighting alone would not look very realistic, so we have ambient occlusion to make objects fit better into their environment. For small-scale occlusion and occlusion from dynamic objects we use a screen-space method known as Horizon-Based Ambient Occlusion (HBAO) . For large-scale occlusion we have a static 3D texture covering the entire game world, each voxel containing the approximate visibility of the sky from that voxel encoded in spherical harmonics. Obviously this can only include occlusion from static objects and only on a fairly large scale since the voxels are huge, but it works very well for ambient shadowing caused by buildings or major terrain formations. Being stored in a 3D volume rather than only on the surfaces of objects allows dynamic objects to be occluded by the static occluders, and also allows occlusion of the sky light for the volumetric stuff.
That’s another high-level look at the technical side of the game wrapped up. We are leaving the office for a few weeks to do some summer vacationing. Alpo will also become a daddy for the second time Any Day Now ™! But despite all that, feel free to ask about any details as usual. There may still be a chance for a reply.
 Bruneton, E. and Neyret, F., Precomputed Atmospheric Scattering, Computer Graphics Forum,Volume 27, Issue 4, pages 1079–1086, June 2008.
 Bavoil, L., Dimitrov, R. and Sainz, M., Image-space horizon-based ambient occlusion, ACM SIGGRAPH 2008 talks, Article 22.