Mapping & Hammer

Source Engine Lighting Guide: Lighting GMod Maps Properly

Source Engine lighting explained: light, light_spot, light_environment, HDR compiles, lightmap scale, cubemaps and the most common lighting errors.

Lighting in the Source Engine is mostly precomputed: the compiler VRAD calculates lightmaps from your light entities and stores them in the BSP. For interiors you place light and light_spot, for sun and sky one light_environment. Then you compile with VRAD and build the cubemaps for reflections in game.

The most important light entities

EntityEffectTypical use
lightPoint light, shines in all directionsLamps, base brightness in rooms
light_spotLight cone with an inner and outer angleSpotlights, ceiling spots, street lamps
light_environmentSunlight and skylight for the whole mapOutdoor areas
light_dynamicReal-time light, not precomputedMoving or flickering lights, use sparingly
env_projectedtextureProjected real-time light with dynamic shadowsSingle accents, expensive

The brightness of a light consists of four numbers: red, green, blue and intensity. The falloff settings define how quickly the light fades with distance. Precomputed lights cost practically no performance in game, while real-time lights cost something every frame. Build the mood with light and light_spot and use dynamic lights only on purpose.

Sun and sky: light_environment and the skybox

A light_environment lights the map through all faces textured with tools/toolsskybox. Three values matter:

  • Brightness and Color: colour and strength of the direct sunlight.
  • Ambient Color and Brightness: the diffuse skylight. It brightens shadows and decides how dark areas without direct sun are.
  • Pitch and Yaw: the direction the sun shines from.

SunSpreadAngle makes sun shadows softer. The skybox texture itself is set under Map > Map Properties. Light colour and sun direction should match the sky image, otherwise the scene looks inconsistent. The entity env_sun only draws the sun's glow in the sky and does not light anything.

If you want to show distant landscape, read the 3D skybox guide.

Compiling HDR or LDR

VRAD can calculate lighting in two variants: LDR (classic brightness range) and HDR (extended range with automatic exposure). The parameters are -ldr, -hdr and -both. Without any of them, GMod's VRAD only calculates LDR. In Hammer's normal compile dialog, the "HDR" checkbox compiles both.

  • LDR is enough for quick tests.
  • For release, compile with -both. The map then looks right for players with and without HDR. Lighting is calculated twice, so VRAD takes correspondingly longer.

In HDR maps, env_tonemap_controller controls the automatic exposure. Without it the engine's default exposure range applies, and that does not suit every map. Lights also have their own HDR brightness values. The default -1 -1 -1 1 means the normal value is used. How the compile steps fit together is covered in VBSP, VVIS and VRAD explained.

Lightmap scale and shadow quality

The lightmap scale of a face states how many units one lightmap sample covers. The default is 16. You change it in the texture tool (Shift+A).

  • Smaller values such as 8 or 4 give sharper shadows but cost memory, file size and compile time.
  • Larger values such as 32 or 64 are cheap and sufficient for large, evenly lit surfaces.

These VRAD parameters improve quality for the final compile:

  • -final: more accurate light calculation, considerably slower.
  • -StaticPropLighting: calculates lighting for prop_static per vertex of the model instead of at a single point.
  • -StaticPropPolys: uses the visible shape of props for shadows instead of the coarse collision model.
  • -TextureShadows: takes transparent textures into account for prop shadows, provided the models are registered for it in a RAD file or were compiled for it. It usually only has an effect together with -StaticPropPolys.

Reflections with env_cubemap

Shiny surfaces do not reflect the real surroundings but a panorama captured in advance. That is what env_cubemap entities are for:

  1. Place at least one env_cubemap per room or lighting mood, roughly at head height and not inside geometry.
  2. Compile the map and load it in game.
  3. Type buildcubemaps into the console.
  4. If you compiled with -both, build the cubemaps once for LDR and once for HDR. In between, switch with mat_hdr_level and reload the map.

After every new compile you have to build the cubemaps again. Common problems are covered in Fix cubemap reflections.

Typical lighting errors

  • Fullbright: Everything is evenly bright and without shadows. The map then contains no lighting data. Either there is no light entity, or VRAD was not run or aborted. Check the compile log.
  • Map too dark: Often the ambient value of the light_environment is too low, or interiors lack fill lights. Weak additional light entities and brighter surfaces help, because bright textures bounce more light.
  • Hard, blocky shadow edges: The lightmap scale is too coarse. Lower it on the affected faces. Visible lighting seams on rounded brush geometry are removed with smoothing groups.
  • Black props: Without -StaticPropLighting a prop_static is lit at a single point. If that point is in the dark or inside a wall, the whole model turns black. An info_lighting as lighting origin fixes this.
  • Too many light styles: Lights with a name or a flicker style need their own lightmaps. If many of them overlap on one face, VRAD warns.
  • Leak: With a leak VVIS delivers no visibility data, and VRAD then only calculates direct light without bounces. Fix the map leak error first.

You can paste messages from the VRAD log into the Map Scanner. It matches known messages to causes and fixes.

FAQ

Why is my map fullbright?

The BSP contains no lighting data. This happens when there is not a single light entity in the map, or when VRAD was skipped during the compile or aborted with an error. Place a light, compile with RAD set to "Normal" and check the log.

How many light_environment entities may a map have?

One. Sun and sky apply to the entire map. Several entities with different values do not produce different lighting in different areas.

Do I have to compile with HDR?

No, an LDR-only map works. For a published map, -both is the safe choice, because the map is then lit correctly regardless of the players' graphics settings.

Why do reflections look wrong after compiling?

The cubemaps have not been built for this compile yet. Every new compile discards them. Load the map, run buildcubemaps and restart the map.