# Lighting

> Add point, spot and directional lights, bake light probes for interiors, and configure sun shadows, screen-space reflections and bounce lighting.

Source: https://feather-engine.com/docs/rendering/lighting/

Scenes are lit by the sun or moon, the sky, and the lights you place. For interiors, caves and
alleys, baked **light probes** replace the flat outdoor ambient with bounce light and sky visibility,
so enclosed spaces darken naturally and take on their lamps' colour. Screen-space reflections and
screen-space bounce lighting add dynamic detail on top.

The sun's position, the time of day and the lighting looks are covered in
[Sky, weather and climate](/docs/world/sky-weather-climate/).

## Add a light

1. Select an object, such as a lamp post or a torch model.
2. In the Details panel, click **Add Component → Light**.
3. Pick a **Preset**, then adjust the fields. Applying a preset keeps the light's offset on the object.

| Preset | Kind | Description |
| --- | --- | --- |
| Candle | Point | A small warm flame that flickers |
| Torch | Point | Warm, flickering, casts shadows |
| Lantern | Point | Lights up at night |
| Lamp | Point | A neutral electric lamp |
| Neon | Point | A saturated neon glow |
| Spotlight | Spot | A crisp cone with shadows |
| God Rays | Spot | A soft volumetric spot that draws shafts through the fog |
| Moonlight | Directional | A cool moonlight for night scenes |
| Key Light | Directional | A strong warm key light, like a second sun |
| Rim Light | Directional | A soft cool rim light without shadows |

### Light settings

| Setting | Field | Range | Default | Description |
| --- | --- | --- | --- | --- |
| Kind | `kind` | Point / Spot / Directional | Point | A directional light shines straight down until you rotate the object |
| Colour | `color` | sRGB | White | |
| Temperature | `temperature` | 1,000–12,000 K in the panel; 0 turns it off | 0 | 1,000 is a candle, 2,700 a lamp, 6,500 daylight |
| Intensity | `intensity` | Up to 200,000 lm (point, spot) or 150,000 lux (directional) | 12,000 | |
| Range | `range` | 0.5–100 m in the panel, up to 200 by command | 14 m | Point and spot only |
| Cone | `spot_angle` | 1–89° | 35° | Spot only |
| Hard edge | `inner_angle` | 0 (soft) – 1 (hard) | 0.8 | Spot only |
| Source radius | `source_radius` | 0–2 m in the panel, up to 10 by command | 0 | Larger values give softer highlights |
| Offset | `offset` | −100 to 100 m | — | Position relative to the object, for example the lamp head |
| Flicker | `flicker` | 0 (steady) – 1 (wild) | 0 | |
| Cast shadows | `shadows` | On/off | Off | |
| Only at night | `night_only` | On/off | On | Fades the light in only when the sun is down |
| Volumetric | `volumetric` | On/off | Off | Lights the volumetric fog, for halos and shafts. Needs volumetric fog turned on |

:::tip
**Only at night** is on by default, so a new light stays dark at midday. Turn it off for lights that
should always shine.
:::

### Change lights from scripts

During Play, scripts dim, brighten or recolour a light object:

| Function | Description |
| --- | --- |
| `set_light(id, brightness)` | Scales the light's authored brightness, from 0 (off) to 20. A colour set earlier is kept |
| `set_light(id, brightness, r, g, b)` | The same, with a new sRGB colour (each 0–1) |

The scale applies on top of **Only at night** and **Flicker**. Press **Stop** to restore the
authored lights.

```rust
// A world script: the light object named "Alarm lamp" pulses red.
fn update(dt) {
    let lamp = find("Alarm lamp");
    set_light(lamp, 1.0 + (elapsed * 6.0).sin(), 1.0, 0.1, 0.05);
}
```

## Bake light probes

Light probes are baked on the CPU with a path tracer; no GPU is needed. A bake traces the models,
built-in props and landscape near each probe, with albedo from their materials, lit by your lights,
the sun or moon at the bake hour, and the ambient sky.

There are two kinds:

- **Irradiance volumes** are boxes of ambient samples. Inside the box, the baked bounce light and sky
  visibility replace the flat ambient and sky light, blending out over the last metre.
- **Reflection probes** capture a cubemap at their centre, used for reflections and diffuse light
  inside their box.

1. Open **Window → World & terrain → Light probes**.
2. Click **Add volume** or **Add reflection probe**. The probe bounds draw in the viewport.
3. Set the probe's centre, size and yaw to cover the room or cave.
4. Click **Bake** on the probe, or **Bake all**.

Each probe shows its status: **baked**, **unbaked** (no effect until baked), **stale** (the scene
near it changed since the bake, including objects, lights, the sky or the bake settings), or
**missing** (the baked file is not in the asset cache). Re-bake stale probes. Turn off **Draw
probes** to compare against flat ambient.

| Volume setting | Field | Range | Default |
| --- | --- | --- | --- |
| Size | `size` | 0.5–1,000 m per axis | — |
| Yaw | `yaw` | −180 to 180° in the panel | 0 |
| Resolution | `resolution` | 1–32 samples per axis; about one per 1.5–3 m | — |
| Bounce strength | `intensity` | 0–4 in the panel, up to 16 by command | 1 |
| Fill | `fill` | 0–1 | 0.7 |

**Fill** is the share of sky and ambient light kept however enclosed the space is. 0 is physically
dark; graded, stylized scenes can turn low values to black.

| Reflection setting | Field | Range | Default |
| --- | --- | --- | --- |
| Size, Yaw | `size`, `yaw` | As for volumes | — |
| Resolution | `resolution` | 32, 64, 128 or 256 | 128 |
| Intensity | `intensity` | 0–4 in the panel, up to 16 by command | — |

### Bake settings

| Setting | Field | Range | Default |
| --- | --- | --- | --- |
| Rays | `rays` | 16–1,024 in the panel, up to 4,096 by command | 128 per ambient-cube face |
| Bounces | `bounces` | 1–4 | 2 |
| Ray reach | `max_distance` | 5–300 m in the panel, up to 1,000 by command | 80 m |
| Own bake hour / Bake hour | `hour` | 0–23.9 h; −1 uses the environment's time of day | −1 |
| Re-bake on destruction | `runtime_rebake` | On/off | On |

With **Re-bake on destruction** on, destroying objects inside a probe during Play re-bakes it in the
background without them. A 16 × 6 × 16 m room at the default settings bakes in about a second.

## Sun shadows

Open **Window → World & terrain → Post process** and expand **Sun shadows**.

| Setting | Field | Range | Default |
| --- | --- | --- | --- |
| Cascades | `cascades` | 1–4 | 4 |
| Map size | `map_size` | 512, 1024, 2048, 4096 texels | 2048 |
| Sharp shadows reach (m) | `first_cascade_far_bound` | 1–100 m in the panel | 12 m |
| Shadow distance (m) | `max_distance` | 0–1,000 m in the panel; 0 follows the fog distance | 0 |
| Depth bias | `depth_bias` | 0–0.2 in the panel | 0.02 |
| Normal bias | `normal_bias` | 0–10 | 1.8 |

More cascades give sharper near and far shadows at more cost. Raise **Depth bias** if surfaces show
striped shadow acne, and **Normal bias** if slopes do; too much normal bias detaches shadows from
objects. The player's graphics quality sets the shadow map size: 1024 on Low, 2048 on Medium and
4096 on High.

## Reflections and bounce lighting

Both effects are in the **Post process** tab. They switch the camera to the deferred renderer and
replace MSAA with SMAA or TAA.

| Setting | Section | Default | Description |
| --- | --- | --- | --- |
| Screen-space reflections | Reflections and film | Off | Wet stone, water and metal reflect what is on screen |
| Reflective below roughness | Reflections and film | 0.35 | Surfaces smoother than this reflect. Terrain layers set their own roughness |
| Bounce lighting (screen-space GI) | Global illumination | Off | One bounce of diffuse light from what is on screen: a sunlit red wall tints the floor beside it |
| Bounce intensity | Global illumination | 1 | 0–4; 1 is physically based |
| Bounce distance (m) | Global illumination | 6 m | 0.5–30 m; longer reaches across rooms but costs more and misses small detail |

Bounce lighting traces at half resolution and smooths over frames. It is off on the Low graphics
setting.

:::note
Toon-shaded materials render forward, so screen-space reflections and bounce lighting do not land
on them. Baked light probes do.
:::

## Limits

- Up to 8 irradiance volumes and 8 reflection probes are drawn per view.
- A bake processes up to 32 probes per command.
- Screen-space effects only see what is on screen.

## Automate it

This places a torch, adds an irradiance volume around a room, and bakes it:

```bash
feather-cli --connect .feather-session.json command light.add \
  --json '{"preset":"torch","position":[2,1.5,-4],"name":"Hall torch"}'

feather-cli --connect .feather-session.json command probe.add \
  --json '{"kind":"volume","value":{"id":"hall","center":[0,3,-4],"size":[16,6,16],"resolution":[8,3,8]}}'

feather-cli --connect .feather-session.json command lighting.bake_probes \
  --json '{"ids":["hall"]}'
```

| Command | Purpose |
| --- | --- |
| `light.add` | Places a preset light as a new object |
| `scene.update` | Adds or edits a `light` on an object |
| `lighting.get` / `lighting.set` | Reads probe status; patches `probes_enabled` and `bake` settings |
| `probe.add` / `probe.update` / `probe.remove` | Edits irradiance volumes and reflection probes |
| `lighting.bake_probes` | Bakes probes; `stale_only` re-bakes only unbaked, stale or missing ones |
| `project.environment` | Patches the sun `shadows` settings |
| `project.post_process` | Turns screen-space reflections and bounce lighting on or off |

See [Agents & automation](/docs/agents/overview/) for connecting a live session.
