Builtin Library
README.md
VolumetricLighting
The air between the camera and the scene, as a component. Add it to an entity and light travelling through that air scatters toward the viewer, so a lamp becomes a glow rather than an invisible point and the sun cuts shafts where something crosses it.
local id = entity.spawn("air").id
entity(id).component.add("VolumetricLighting", {
density = 0.06,
anisotropy = 0.7,
})
Every field is live — editing one in the inspector changes the air on the next
frame, and the values persist with the scene. Setting density to 0 empties the
air and releases the passes while keeping the rest authored; removing the
last one in the scene clears it.
| field | effect |
|---|---|
density | How much medium there is per world unit at the reference altitude. 0 is off. |
heightFalloff / heightRef | How fast density thins with altitude, and the altitude density is quoted at. 0 falloff fills the scene evenly. |
steps | Samples along each view ray. More resolves a beam's edge more cleanly. |
colorR/G/B | What the medium scatters. Warm dust and cold mist differ here. |
anisotropy | How forward-biased the scattering is, in (-1, 1). Positive values throw light onward, so haze blooms around a source you look toward. |
sunIntensity / sunColorR/G/B | The sun's contribution to the medium. |
lightScale | The scene lights' contribution to the medium. |
shadowSteps / shadowDistance | Samples taken back toward the sun to decide whether a point in the air is lit, and how far they reach. 0 leaves the sun's contribution unshadowed, so the haze glows evenly and no shafts form. |
maxDistance | How far along the view ray the march runs. A ray that escapes to sky stops here. |
The lights are the scene's own, each scattering on the terms its kind emits on: a point fills the air around it, a spot fills its cone, a rect reaches the air on the side its face emits along, and a parallel light lays an even glow across the whole medium. One added, moved, re-aimed or recoloured at runtime changes the glow it throws with nothing to keep in step here.
One body of air fills the scene, so one of these per scene is enough — the last one to push wins.
The work runs in lightScattering.renderFeature; the settings live in
@builtin::systems.volumetrics.volumetricLighting, which is also how to drive
them from a script.