raea/light

Bevy's lights in Bevy's units, environments, skies and daylight.

View as Markdown

These are Bevy's lights in Bevy's physical units: a DirectionalLight in lux, a PointLight and SpotLight in lumens, a RectLight for soft area light, and ambient light. <Daylight> and daylight() place the sun for a time and place; <Environment>, <EnvironmentMapLight> and <Skybox> light a scene from an image; <Atmosphere> draws Bevy's sky. roomExposure gives the camera exposure that suits an indoor scene's lights.

TSX
import { AmbientLight, DirectionalLight, PointLight } from "raea/light";
import { Transform } from "raea/transform";

function Lights() {
  return (
    <>
      <AmbientLight brightness={160} />
      <DirectionalLight transform={Transform.fromXyz(3, 5, 4).lookingAt([0, 0, 0])} illuminance={11200} shadow_maps_enabled />
      <PointLight transform={Transform.fromXyz(-1, 2, 1)} intensity={800000} color="#ffd9a0" />
    </>
  );
}
TS
import { AmbientLight, Atmosphere, bounce, clearSun } from "raea/light"

raea/light exports 15 components, 9 functions, 2 values, 15 types. Bevy's counterpart: bevy_light. Source: sdk/raea/src/light.ts.

Components

AmbientLight

Bevy's AmbientLight (on the camera in 0.20; GlobalAmbientLight is the same light as a resource): light from everywhere, in cd/m².

Bevy: bevy_light::ambient_light::AmbientLight.

Takes AmbientLightProps's props.

Used in: defaults/parts, shader_advanced/deferred_raymarch.

Atmosphere

A procedural sky: Bevy's physically based atmosphere (Earth's air), drawn behind everything and lit by the DirectionalLights, so a sun low on the horizon makes a sunset. Inside the Canvas3D, once.

Bevy: bevy_light::Atmosphere.

Takes AtmosphereProps's props.

Daylight

The day's sun and sky: the sun as a shadowed directional light at its lux and colour, the panorama as the sky seen through the windows at its true brightness (it lights nothing: an Environment is not shadowed, and would light the room as if it had no walls), the room's bounce (indoor, its daylight factor, 2% by default) as an even fill; the windows' own light comes from .

PropTypeWhat it does
day (required)Daythe day outside, from daylight
indoornumberthe room's daylight factor, the share of the outside light its bounce gives as an even fill (0.02)
softShadowboolean | numberthe sun's shadow softness (0.6): true, or a number, as a DirectionalLight's

DirectionalLight

Bevy's DirectionalLight: parallel light shining along its transform's -Z, in lux.

Bevy: bevy_light::directional_light::DirectionalLight.

PropTypeWhat it does
illuminancenumberlux on a surface facing it (Bevy's default 10,000, light_consts::lux::AMBIENT_DAYLIGHT; full sun is about 100,000)
shadow_maps_enabledbooleanBevy: Whether this light casts shadows.
soft_shadow_sizenumber | nullsoft shadows (PCSS): the sun's size as its shadows see it, in metres
childrenReactNodeBevy components on the light: shadow settings, cascades

Also takes the props of LightCommon (color, name, visibility, transform, shadow_depth_bias, shadow_normal_bias, volumetric).

Used in: ui/render_ui_to_texture, 3d/fog_volumes, 3d/shadow_caster_receiver, 3d/split_screen, 3d/pbr, 3d/mesh_ray_cast, 3d/atmospheric_fog, 3d/3d_viewport_to_world, and 15 more.

Environment

Light from all around, out of a panorama: soft light from the sky and reflections of it in every glossy or metal surface (image-based lighting), and with background the panorama as the sky. Put it inside the Canvas3D, once a frame; its src, intensity, rotation and background may change from frame to frame (a cut from a hall to a street). Bevy's EnvironmentMapLight with maps already filtered is . Its panorama is filtered by Bevy's generator and, with background, drawn as the sky (engine/render environment.rs):

Bevy: bevy_light::probe::GeneratedEnvironmentMapLight. Bevy's Skybox from its own cubemap is <Skybox>..

Takes EnvironmentProps's props.

EnvironmentMapLight

Bevy's EnvironmentMapLight with its own prefiltered maps, as Bevy's examples put one on the camera: light from all around and its reflections, from cubemaps already filtered (an filters a panorama itself). Put it inside the Canvas3D, once; the first frame's holds.

Bevy: bevy_light::probe::EnvironmentMapLight.

Takes EnvironmentMapLightProps's props.

Used in: 3d/rotate_environment_map, 3d/animated_material, 3d/pbr, gltf/load_gltf.

GlobalAmbientLight

The same light as a resource, as Bevy 0.20 names it. (A function, not a const alias: an alias would keep 3D code in a 2D bundle through the prelude.)

Takes AmbientLightProps's props.

Used in: 3d/fog_volumes, 3d/fog, 3d/spherical_area_lights, 3d/lightmaps, 3d/spotlight, animation/animated_mesh, animation/animated_transform, gltf/gltf_skinned_mesh.

Pathtracer

Bevy's reference path tracer for the it's inside: slow and exact, accumulating over frames while the view holds still. For stills to check a look against, not for motion. Same GPU needs as .

PropTypeWhat it does
resetbooleanstart the accumulation again

PointLight

Bevy's PointLight: a bulb at its transform's translation, in lumens.

Bevy: bevy_light::point_light::PointLight.

PropTypeWhat it does
intensitynumberlumens (Bevy's default 1,000,000; a 60 W bulb is about 800)
rangenumbermetres it reaches (20)
radiusnumberthe bulb's radius in metres (0): the size of its highlight on shiny surfaces (a spherical area light), and soft shadows' size when soft_shadows_enabled
shadow_maps_enabledbooleanBevy: Whether this light casts shadows.
soft_shadows_enabledbooleanBevy: Whether soft shadows are enabled.
paintbooleanraea's paint look draws this light (3d.tsx's PointLight paint)

Also takes the props of LightCommon (name, transform, visibility, color, shadow_depth_bias, shadow_normal_bias, volumetric, children).

Used in: 3d/fog, 3d/vertex_colors, 3d/rotate_environment_map, 3d/transparency_3d, 3d/spherical_area_lights, 3d/3d_shapes, 3d/shadow_caster_receiver, 3d/two_passes, and 18 more.

RectLight

Bevy's RectLight: a rectangle of light facing its transform's -Z, in lumens (no shadows in Bevy 0.20).

Bevy: bevy_light::rect_light::RectLight.

PropTypeWhat it does
intensitynumberlumens (1,000,000)
rangenumberBevy: Cut-off for the light's area-of-effect. Fragments outside this range will not be affected by this light at all, so it's important to tune this together with intensity to prevent hard lighting cut-offs.
widthnumberits face's size in metres (1 x 1)
heightnumberBevy: Height of the light rectangle (along local Y).

Also takes the props of LightCommon (color, visibility, transform, shadow_depth_bias, shadow_normal_bias).

Used in: 3d/rect_light.

Shadows

Shadow quality for every light in the Canvas3D: map size, the sun's cascades, biases, filtering. Put it inside the Canvas3D, once; the first frame's holds for the piece. mapSize sets both shadow maps' size, filter the camera's filtering, and the cascade props the sun's cascades (engine/render scene3d.rs):

Bevy: bevy_light::directional_light::DirectionalLightShadowMap, bevy_light::point_light::PointLightShadowMap, bevy_light::ShadowFilteringMethod, bevy_light::cascade::CascadeShadowConfig.

Takes ShadowsProps's props.

Used in: 3d/split_screen, stress_tests/many_foxes, animation/animated_mesh.

Skybox

Bevy's Skybox: a cubemap drawn behind everything, as Bevy's examples put one on the camera. Put it inside the Canvas3D, once; its brightness and rotation may change each frame (an 's background is the sky of a panorama raea filters).

Bevy: bevy_light::probe::Skybox.

Takes SkyboxProps's props.

Used in: 3d/rotate_environment_map.

SolariLighting

Ray-traced direct and indirect light for the it's inside (Bevy's SolariLighting): shadows, bounce light and reflections traced against the scene, in place of shadow maps. Needs a GPU with ray queries (Apple silicon on Metal, RTX on Vulkan); elsewhere the scene draws raster-lit and raea says so. On the Mac MetalFX's temporal denoiser cleans it up (RT4; RAEA_SOLARI_DENOISE=0 shows the raw noise). A (skinned, morphed) stays raster-lit: Bevy 0.20's Solari can't trace it.

PropTypeWhat it does
restirbooleanReSTIR: reuse light samples between pixels and frames (finer shadows, steadier in hard light; slower). Off by default, as Bevy has it
bouncesnumberhow many times light bounces (Bevy's default when left out)
resetbooleanstart the lighting's history again (a cut)

SpotLight

Bevy's SpotLight: a cone along its transform's -Z, in lumens.

Bevy: bevy_light::spot_light::SpotLight.

PropTypeWhat it does
outer_anglenumberthe cone's half-angle in radians (Bevy's default PI/4), up to PI/2
inner_anglenumberwhere the light starts to fall off, in radians from the axis (0)

Also takes the props of PointLightProps (intensity, range, radius, shadow_maps_enabled, soft_shadows_enabled, paint); LightCommon (name, transform, visibility, color, shadow_depth_bias, shadow_normal_bias, volumetric, children).

Used in: 3d/spotlight, defaults/parts.

WindowLight

A window's light as a lamp (windowLight), wide and soft, shadowed.

PropTypeWhat it does
day (required)Daythe day outside
room (required)Roomthe room the window is in
opening (required)Openingthe window: one of the room's openings
transmitnumberthe share of light the glass lets through (0.75)
groundnumberthe ground's reflectance outside (0.2)
namestringthe light's name (window-WALL-AT by default)

Functions

bounce

The room's bounce: the light every surface gets from the room's other surfaces once the windows' light has struck them, as luminance (a daylight factor indoor of the day's light on the ground, over π) and colour (the sun's and the sky's, mixed in mired by their shares of it). Not the sky's colour: a room's fill is its sunlit floor and walls.

TS
function bounce(day: Day, indoor?: number): { nits: number; kelvin: number; }

clearSun

A clear sky's direct sun at elevation degrees, lux on a surface facing it: the solar constant's light (1361 W/m² at 93 lm/W) through the air mass (Kasten and Young) by Meinel's attenuation.

TS
function clearSun(elevation: number): number

daylight

The day from a sky panorama and, to put the sun where it was, a place and time (else the panorama's own sun). An overcast panorama (no sun) is lit as an overcast sky of overcastLux on the ground (10 000 by default).

TS
function daylight(o: { sky: string; lat?: number; lon?: number; time?: string; north?: number; overcastLux?: number; }): Day

kelvin

A colour temperature as a light's colour (Tanner Helland's fit to the Planckian locus), sRGB hex.

TS
function kelvin(k: number): string

readSky

A sky panorama read by the engine: its sun (if it has one) and its light's split (scene.sky).

TS
function readSky(src: string, rotation?: number): SkyRead

roomExposure

The exposure a camera sets for the room, as : an incident meter's EV100 (log2 E·100/250, as raea scene light reads it) on the room's light, its bounce (indoor, as Daylight's) plus extra lux, and the engine's exposure for it (EV100 = 9.7 - exposure). The windows burn out, as a room's do in a real camera.

TS
function roomExposure(day: Day, indoor?: number, extra?: number): number

sunDirection

The world direction toward a sun at azimuth and elevation (degrees), north along -z turned by north (radians about +y: where the set's north is), east along +x.

TS
function sunDirection(azimuth: number, elevation: number, north?: number): Vec3

sunPosition

Where the sun stands at a place and moment (NOAA's low-precision solar position, good to a few tenths of a degree): azimuth from north, clockwise, and elevation over the horizon, in degrees. time is ISO 8601 with its offset.

TS
function sunPosition(lat: number, lon: number, time: string): { azimuth: number; elevation: number; }

windowLight

What a window lets in besides the sun: its sky above and the ground below (ground its reflectance), seen through glass of transmit, as a lamp in the opening that faces into the room with a window's candela on its axis (a Lambertian pane: luminance times area). A bay's three faces count as its mouth.

TS
function windowLight(day: Day, room: Room, o: Opening, { transmit, ground }?: { transmit?: number; ground?: number; }): { position: Vec3; target: Vec3; lumens: number; color: string; candela: number; }

Values

light_consts

Bevy's named light values (bevy_light light_consts), for a light's own units: illuminance={light_consts.lux.DIRECT_SUNLIGHT}, intensity={light_consts.lumens.VERY_LARGE_CINEMA_LIGHT}.

Used in: 3d/shadow_caster_receiver.

UNITS

The engine's one relative unit left (core/scene props.rs ENV): an Environment of 1 is its panorama times 1000 cd/m². Lights are given in Bevy's own units.

Types

AmbientLightProps

FieldTypeWhat it is
namestringthe entity's name, for picking, the inspector and world.*
colorstringits colour, as CSS writes one (a name, hex, rgb())
brightnessnumbercd/m² (Bevy's default 80)

AtmosphereProps

FieldTypeWhat it is
lightbooleanit lights the scene too, as a sky does (ambient and reflections from the sky it draws)
groundAlbedonumberthe ground's brightness the air's scattering sees, 0..1 (0.3 by default)

Day

The day outside, in physical units, for one set.

FieldTypeWhat it is
sky (required)stringthe sky panorama's file
rotation (required)numberthe panorama's turn that puts its sun where the day's is (radians, as )
sunDir (required)Vec3toward the sun, world
sunLux (required)numberthe sun's lux on a surface facing it, its colour temperature
sunK (required)numberthe sun's colour temperature, kelvin
sunGround (required)numberthe sun's and the sky's lux on level ground outside
skyGround (required)numberthe sky's lux on level ground outside
skyNits (required)numberthe sky's mean luminance (cd/m²) and colour temperature
skyK (required)numberthe sky's colour temperature, kelvin
scale (required)numbercd/m² per unit of the panorama
elevation (required)numberthe sun's elevation (degrees) the light was made for, and the panorama's own (a different height shows in its shadows' length outside, never in the room's light)
skyElevation (required)number | nullthe panorama's own sun elevation, degrees (null for an overcast one)

DaylightProps

The props of Daylight, tabled there.

DirectionalLightProps

The props of DirectionalLight, tabled there.

EnvironmentMapLightProps

FieldTypeWhat it is
diffuse_map (required)stringthe prefiltered diffuse (irradiance) cubemap, a.ktx2 file: staticFile("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2")
specular_map (required)stringthe prefiltered specular (radiance) cubemap with its mips, a.ktx2 file
intensitynumbercd/m² (Bevy's default 1)
rotation[number, number, number, number]its turn, glam's Quat [x, y, z, w] (Bevy's identity): Quat.from_rotation_y(0.2 * t) turns it each frame

EnvironmentProps

FieldTypeWhat it is
src (required)stringan equirectangular panorama in the media folder: a Radiance.hdr (Poly Haven's), an OpenEXR.exr, or an 8-bit.png/.jpg. Change it between frames to cut from one place to another
intensitynumberhow strongly it lights the scene (1 by default: a sky about as bright as an AmbientLight of 2.5 overall); animate it, or set 0 to switch it off for a shot
rotationnumbera turn about the vertical axis, in radians, for both the light and the sky: puts the sun where the shot wants it
backgroundbooleandraw the panorama as the sky behind everything (off by default: light only)
backgroundIntensitynumberthe sky's brightness, when it should differ from the light's (intensity by default)

PathtracerProps

The props of Pathtracer, tabled there.

PointLightProps

The props of PointLight, tabled there.

RectLightProps

The props of RectLight, tabled there.

ShadowsProps

FieldTypeWhat it is
mapSize1024 | 2048 | 4096 | 8192each shadow map's size in texels (4096 by default; 8192 is sharper still, at four times the memory and about 2-3 ms a frame at 1080p)
distancenumberhow far from the camera the sun's shadows reach, in metres (150 by default): the shorter, the sharper they are
firstCascadenumberwhere the sun's first, sharpest cascade ends, in metres (8 by default): the distance of the nearest subject
cascadesnumberhow many cascades split the distance (4 by default, 1-4)
overlapnumberhow much neighbouring cascades overlap, 0-1 (0.3 by default) so the seam between them doesn't show
biasnumberdepth bias: raise it if surfaces facing the light show stripes of their own shadow (acne); too high and shadows detach from what casts them (0.02 by default for the sun, as Bevy's)
normalBiasnumbernormal bias, in texels: the same trade-off along the surface's normal (1.8 by default for the sun)
filter"gaussian" | "hardware""gaussian" (the default: soft, smooth edges) or "hardware" (2x2, crisper and cheaper)

SkyboxProps

FieldTypeWhat it is
image (required)stringthe sky's cubemap, a.ktx2 file (Bevy's examples use the specular map: environment_maps/pisa_specular_rgb9e5_zstd.ktx2)
brightnessnumbercd/m² (Bevy's default 0, a black sky: Bevy's examples give it 1000 to 5000)
rotation[number, number, number, number]its turn, glam's Quat [x, y, z, w] (Bevy's identity)

SolariLightingProps

The props of SolariLighting, tabled there.

SpotLightProps

The props of SpotLight, tabled there.

WindowLightProps

The props of WindowLight, tabled there.