Builtin Library
README.md
PhysicalAtmosphere
The air the scene is seen through, as a component.
local id = entity.spawn("atmosphere").id
entity(id).component.add("PhysicalAtmosphere", {
aerial = 1.0, -- how much of the result reaches the image
sky = true, -- the visible sky comes from the same scattering
worldUnitsPerKm = 1000, -- 1 world unit is a metre
})
Distance starts costing contrast and saturation the way it does outdoors: a ridge kilometres away shifts toward the sky's colour instead of rendering at full contrast as though it were metres away.
With sky on, the visible sky comes out of the same scattering integral as the
air in front of the geometry, so the two agree at the horizon by construction
and the sky's colour follows the sun's elevation — sunrise, midday and dusk
with no per-time-of-day authoring.
Every field is live: edit one in the inspector and the atmosphere follows.
Setting aerial to 0 with sky off turns it all off without losing the rest of
the settings.
worldUnitsPerKm is the field to get right first. Scattering is computed in
kilometres against Earth's coefficients, so this is what maps the scene onto
real atmospheric distances — set it too low and a courtyard fogs like a valley.
The sun's direction and brightness are read from the scene's own directional light, so a day cycle needs nothing on this component to move.
groundAlbedo and sunColor are the two fields that give the scattering a hue.
groundAlbedo is the reflectance of the ground the sky is lit over and feeds
the multiple-scattering term, so a warm ground carries its colour up into the
air; sunColor tints the light entering the atmosphere, colouring the sky and
the aerial perspective together. The rest of the fields move the sky between
Earth's blue and a neutral grey.
entity(id).component.add("PhysicalAtmosphere", {
sky = true,
groundAlbedo = { 0.68, 0.44, 0.23 }, -- warm dust underfoot
sunColor = { 1.0, 0.60, 0.30 }, -- and a low ochre sun
})
For code that adjusts the atmosphere at runtime, reach for
@builtin::systems.atmosphere.atmosphere — same options, no component.
The full description of what each knob does and how the passes work is in the
package readme: guides { path = "systems/atmosphere" }.