API reference

Every public class, method, and event in @codexo/exojs. Generated from source.

C

classRadianceLighting

@codexo/exojs-lighting / lighting / stable

Lighting as radiance that propagates, filled by a chain of cascades traced over this frame's geometry. ```ts const lighting = new RadianceLighting(app, { probeSpacing: 2, interval: 1, bounce: 0.5 }); scene.systems.add(lighting); lighting.occludeFrom(new PhysicsOccluder(world)); ``` Light propagates from what emits rather than falling off inside each light's radius, so a lamp fills the room it stands in, a wall between two rooms leaves the second one dark, a source with a size casts a penumbra that widens with distance, and a lit surface gives part of that light off again in its own colour (see RadianceLightingOptions.bounce). A `SpotLight` emits across its cone and a `SunLight` is the sky every unblocked ray ends in. It does NOT make a scene look the way LightmapLighting makes it look, and it is the only renderer whose cost is per probe rather than per light. Registered normal surfaces are recorded and ignored: the gather averages a probe's rays into one arriving colour, which leaves no incident direction for a normal to be measured against. The host is required and is the first argument. Float render targets are required too - a field of radiance has no ceiling to clamp at - and a device without them is refused at construction rather than shaded differently under the same name.

11
props
11
methods
0
events
Import
import { RadianceLighting } from '@codexo/exojs-lighting'

Lighting as radiance that propagates, filled by a chain of cascades traced over this frame's geometry.

```ts const lighting = new RadianceLighting(app, { probeSpacing: 2, interval: 1, bounce: 0.5 });

scene.systems.add(lighting); lighting.occludeFrom(new PhysicsOccluder(world)); ```

Light propagates from what emits rather than falling off inside each light's radius, so a lamp fills the room it stands in, a wall between two rooms leaves the second one dark, a source with a size casts a penumbra that widens with distance, and a lit surface gives part of that light off again in its own colour (see RadianceLightingOptions.bounce). A `SpotLight` emits across its cone and a `SunLight` is the sky every unblocked ray ends in.

It does NOT make a scene look the way LightmapLighting makes it look, and it is the only renderer whose cost is per probe rather than per light. Registered normal surfaces are recorded and ignored: the gather averages a probe's rays into one arriving colour, which leaves no incident direction for a normal to be measured against.

The host is required and is the first argument. Float render targets are required too - a field of radiance has no ceiling to clamp at - and a device without them is refused at construction rather than shaded differently under the same name.

Constructors1
Methods11
add(light: T): T
Register a light and return it, so it can be created, parented and registered in one expression. Registering the same light twice shades it twice; the second registration is ignored instead.
clear(): this
Unregister every light.
clearOccluders(): this
Unregister every occluder source.
clearSurfaces(): this
Unregister every normal surface.
destroy(): void
Release the renderer's resources. Registered lights and sources are unregistered, not destroyed.
Give a drawable surface normals, and return it so it can be created, parented and registered in one expression. ts lighting.normalsFrom(crate, new NormalMap(crateNormals)); Only lightmap reads these. forward shades inside the sprite stage and takes its normals from LitMaterial instead, and radiance gathers each probe's rays into one arriving colour, which leaves no incident direction at a fragment for a normal to be measured against - under both, registering a surface is recorded and ignored, and activeSurfaceCount stays at zero. Nothing is required of a drawable that is not registered: it is lit as a plane, which is what the renderer already assumed of everything. The drawable and the source are the caller's; the system only reads them. Registering the same drawable twice replaces its source rather than describing the surface twice.
occludeFrom(source: T): T
Register something that blocks light, and return it so it can be built and registered in one expression. Only a renderer with shadows reads them - forward has no light field to darken, and skips collecting entirely. ts lighting.occludeFrom(new PhysicsOccluder(world)); The source is asked, once per frame, for the edges in the region the visible lights jointly reach. It is the caller's; the system only reads it. Registering the same source twice collects it twice, so the second registration is ignored instead.
update(): void
System update phase: publish this frame's lights, occluders and surfaces to the renderer.
Properties11
activeLightCount: number
Lights the last frame actually shaded with. Lower than lights when some are disabled, have no intensity, or fall beyond what the renderer in use can carry.
activeSurfaceCount: number
Surfaces the last frame actually took normals from. Lower than surfaces when some are hidden or carry no texture, and zero under every renderer but lightmap. See normalsFrom.
debugExposure: number
Scale applied to the shaded output, 1 by default. It moves the exposure only: the lights, the transport and the bounce history are all untouched, so raising it shows what a light field holds above 1.0 without changing what any of it computed. That is what makes it the right knob for looking at an overbright scene - turning a light down instead would change the scene being looked at. Under forward, where nothing is composited, it does nothing. It is not a tone map: values still clip, one stop further along.
hdr: boolean
Whether light accumulates with headroom above 1.0, so that overlapping lights add up instead of saturating to white and a filter over the frame has something above the clipping point to work with. false under forward, which shades straight into the frame, and under lightmap on a WebGL2 context without EXT_color_buffer_float. The picture is still correct there - it clips earlier, and a bloom keyed on a threshold near 1.0 finds little to bloom.
Registered normal surfaces, in registration order.
Source