Ambient light

From Valve Developer Community
(Redirected from R radiosity)
Jump to: navigation, search

Ambient light is the general amount of light that models receive from their environment. Compared to dynamic direct lights, ambient light is the light that is "already there" and is often the most significant contributor to model lighting in the absence of intense direct lights. In Source, ambient light comes exclusively from static map light sources that are created in Hammer. It is pre-calculated by VRAD during map compile and reduced to a small but relatively accurate approximation for use at runtime.

Stage 1: Hammer

The map creator must place one or more static light sources in the map. These are the only light sources which contribute to VRAD's simulation and are thus the only way to add ambient light to a map.

Stage 2: VRAD and Ambient Cubes

Ambient cubes within the red-outlined visleaf. Note how the "left" side of several cubes is brighter than the front - this is the result of the bright sunlight reaching the cubes after reflecting off the angled wall.

VRAD runs an extensive radiosity simulation, calculating the emission, reflection, and absorption of light within the entire sealed volume of the world. Light originates from static map lights, bounces off world surfaces, and is attenuated per the material parameters of those surfaces and the lights.rad file. When the simulation is complete, it is possible to sample any arbitrary position in the world's volume and receive the total amount of incoming light from all directions at that position. This now becomes the ambient light at that position.

VRAD's work is exceptionally slow and is not feasible for realtime rendering. Additionally, storing the entire result of the simulation in the bsp would create prohibitively massive map files. To optimize both ingame rendering and storage, VRAD only stores a tiny number of ambient light samples in the map file. Each visleaf receives only a sparse handful of samples, known as "ambient cubes", which are distributed throughout the visleaf. VRAD attempts to evenly balance the distribution of ambient cubes among differently sized visleafs, but smaller visleaves will typically have more ambient cubes than larger ones. Each ambient cube only stores the incoming ambient light from the 6 cardinal directions that align with the normals of the cube's 6 faces. When ingame, the commands mat_leafvis 1 and r_visambient 1 will reveal the ambient cubes.

Stage 3: In the Engine

Forward rendering in Source. Note the "Ambient Cube" pass, wherein Alyx is subtly illuminated by gray-blue light bouncing off the gray-blue walls.

With VRAD's enormous simulation reduced to just a few thousand ambient cubes, approximate realtime ambient lighting is now feasible. The ambient cubes provide two types of incoming light: direct and indirect. All ambient light is sampled relative to the model's $illumposition and the nearest ambient cube(s); there is no per-vertex or per-pixel ambient lighting technique.

Tip.pngTip:The role of $illumposition is why models sometimes appear much darker than they should when placed against a wall or near an elevation change in the ground. The $illumposition is now proximal to an ambient cube that is on the other side of the wall or ground.

Direct Ambient Light

All entities always receive direct ambient light from the nearest ambient cube. This is light which originates from the faces of the ambient cube (as pre-calculated by VRAD during map compile) and directly hits the surface of the model.

Indirect Ambient Light

There are several available techniques to add approximate indirect ambient light to models; all are optional and controlled by the cheat-protected r_radiosity convar.

Indirect ambient light is the light which bounces off nearby surfaces before reaching the model, thus slightly modulating the color of the model with the color of the bounced surface. It primarily adds realism by contributing the subtle color changes across a model's surface that are expected in large, open areas with many varied light sources (such as an outdoor sky). It also helps "fill in" the dark spots and tight crevices on a model.

Compared to direct ambient light, indirect ambient light is typically a much lesser term and is not immediately obvious in most situations. Indirect ambient light is most easily observed in a well-lit area where a curved, predominantly white model is placed near a richly colored surface, e.g. a white egg sitting on a bright green carpet. Neither the egg nor the carpet are specular, but the underside of the egg will be tinted green as it is illuminated by light that reflects off the carpet.

  • Dynamically-lit objects, including players & dynamic props, have their indirect ambient lighting calculated every frame, since these objects move around. The lighting technique uses either the map's ambient cubes for a cheap approximation (modes 1, 3, and 4) or a more expensive but still very limited raytracing routine (mode 2). The raytracing routine produces the most characteristic lighting, since it is the only mode which incorporates the color of local surfaces, notably the ground and the skybox.
  • Statically-lit objects, such as static props placed in Hammer, have their indirect ambient lighting calculated only once, when the map is loading. Since their lightning is only rendered once, most of the r_radiosity choices (modes 2, 3, and 4) use the aforementioned raytracing routine for static props. Changing the convars which control ambient lighting requires restarting the map to re-render the lighting for these static props.

See the r_radiosity convar below for more information on the various indirect ambient lighting modes.

Todo:Add a section fully explaining the concept, purpose, and application of the ambient boost mechanic.

Console commands

mat_leafvis 1; r_visambient 1
These two commands together enable the display the ambient lighting sample points in the active leaf.
r_flashlightambient <int>
Seems like it would be used for making ambient light originating from projected textures or for influencing the color of the flashlight based on ambient light. Does not do anything in Half-Life 2.
r_lightcache_numambientsamples <int>
Cheat. The number of random directions to fire rays when computing ambient lighting. Default 162. Requires map restart.
Confirm:This only affects static props.
r_ambientlightingonly <bool>
Cheat. Light models with only ambient lighting; requires map restart.
r_radiosity <int>
Cheat. Selects the extent and technique used to calculate indirect ambient lighting on entities. Mode 2 typically produces the most interesting lighting.
  • 0 = No indirect ambient light
VRAD-compiled lights only contribute direct ambient light to models.
  • 1 = Cheap indirect ambient light on everything
All models receive a very rough approximation of indirect ambient light from the nearest ambient cube, using only the light calculated along the cube's 6 axis-aligned normals.
  • 2 = Raytraced indirect ambient light on everything
All models receive a greatly improved approximation of indirect ambient light from their own position. Indirect ambient light is calculated from r_lightcache_numambientsamples directions originating from the model's $illumposition, arranged in a sphere for equal coverage. With the default value of 162 for r_lightcache_numambientsamples, models will typically appear brighter with r_radiosity 2 compared to r_radiosity 1. Compared to mode r_radiosity 4, this mode is better at accurately representing the indirect ambient light received from surfaces that are local to the model, such as the ground or the skybox.
  • 3 = Raytraced indirect ambient light on static props, cheap indirect ambient light on everything else
Static props receive indirect ambient light per r_radiosity 2, while everything else receives indirect ambient light per r_radiosity 1. This is the default value for most Source games.
  • 4 = Raytraced indirect ambient light on static props, reconstructed indirect ambient light on everything else
Static props receive indirect ambient light per r_radiosity 2, while everything else receives indirect ambient light from an alternate version of r_radiosity 2. Instead of firing 162 rays from the model's $illumposition until they hit a surface, r_radiosity 4 only gathers incoming indirect ambient light from the ambient cubes in the visleaf containing the model. Since there are often very few ambient cubes in any visleaf compared to 162 r_lightcache_numambientsamples, this mode is often faster than r_radiosity 2 while still producing a visually similar result. However, the spareness of the ambient cubes and their great variation in location will fail to accurately represent the light received from bounces off extremely local surfaces, such as the ground. The end result is that dark spots, tight crevices, and the underside of the model tend to receive more light than they should, reducing the contrast of the model's curvature and making it appear brighter and "flatter". Finally, this mode does not account for the map's lightstyle, causing models to appear much brighter than they should when lightstyle is used to reduce the overall map light.
  • Values below 0 or above 4 are myths and are equivalent to r_radiosity 0.
r_ambientboost <bool>
Boosts ambient term if it is totally swamped by local lights.
r_ambientmin <float>
Threshold above which ambient cube will not boost (i.e. it's already sufficiently bright). Default 0.3.
r_ambientfraction <float>
Cheat. Fraction of direct lighting that ambient cube must be below to trigger boosting. Default 0.1.
r_ambientfactor <float>
Boost ambient cube by no more than this factor. Default 5.