environment
Environment / reflection capture — bake the scene into reflection-probe cube slots from world positions, persist them as faces6 .texture assets, and set per-probe blend data so surfaces reflect the nearest probe(s).The generic "render the scene into a cubemap from a point" capability the reflection probe system is built on.
require("@builtin::modules.api.engine.environment") -- environment (also available as global 'environment')
The environment namespace: 33 functions.
globals/environment/capture
environment.capture(x: number, y: number, z: number) -> boolean
Bake the scene into the environment from (x, y, z) as the single global
reflection (slot 0 + one full-coverage probe). Every PBR surface reflects it.
Queued — takes effect on the next frame. For multiple proximity-blended
probes use the reflectionProbe system instead.
Parameters
xnumber— World X of the capture position.ynumber— World Y of the capture position.znumber— World Z of the capture position.
Returns boolean — True — the capture was queued.
environment.capture(0, 2, 0)
globals/environment/captureSky
environment.captureSky(x: number?, y: number?, z: number?) -> boolean
Render the SKY alone into the environment's sky slot from (x, y, z) and
arm the sky fallback. A reflective surface no probe covers then reflects the
sky rather than black, and a partially covered one blends the shortfall
against it. The capture holds whatever the scene's sky draws — a gradient, a
physical atmosphere, a skybox material — with no geometry in it, so it stays
correct wherever the camera goes. Once captured, the slot follows the sky
the scene draws: a sky that changes is recaptured from the same position.
Queued — takes effect on the next frame.
Parameters
xnumber(optional) — World X of the capture position. Defaults to 0.ynumber(optional) — World Y of the capture position — the altitude a height-dependent atmosphere is sampled at. Defaults to 0.znumber(optional) — World Z of the capture position. Defaults to 0.
Returns boolean — True — the sky capture was queued.
environment.captureSky()
globals/environment/captureSlot
environment.captureSlot(slot: number, x: number, y: number, z: number) -> boolean
Bake the scene into reflection-probe slot from (x, y, z).
Renders the FULL scene (geometry + sky) six times from that
point into that slot. Register the probe's position+radius via setProbes
so surfaces blend it by proximity. Queued — takes effect next frame.
Parameters
slotnumber— Reflection-probe slot (0-based).xnumber— World X of the capture position.ynumber— World Y of the capture position.znumber— World Z of the capture position.
Returns boolean — True — the capture was queued.
environment.captureSlot(0, 0, 2, 0)
globals/environment/captureSlotToAsset
environment.captureSlotToAsset(name: string, slot: number, x: number, y: number, z: number, timeoutFrames: number?) -> (string?, string?)
Bake the scene into reflection-probe slot from (x, y, z) AND persist
the 6 rendered faces into a faces6 .texture cubemap asset at
/source/<name>.texture/ (px/nx/py/ny/pz/nz PNGs + a cube.yaml sidecar).
Survives an engine restart and syncs like any other texture. Yields a few
frames while the bake + GPU readback complete; must be called from a
task/coroutine context (component hook, task.spawn, or execute).
Parameters
namestring— Destination asset identity (writes/source/<name>.texture/).slotnumber— Reflection-probe slot (0-based).xnumber— World X of the capture position.ynumber— World Y of the capture position.znumber— World Z of the capture position.timeoutFramesnumber(optional) — Optional max frames to wait for the readback (default 900, past the frames the engine gives a readback before it gives up on one, so what ends the wait is the readback's own answer).
Returns (string?, string?) — The asset path on success, or (nil, errorMessage) on failure.
environment.captureSlotToAsset("probe_lobby", 0, 0, 2, 0)
globals/environment/captureToAsset
environment.captureToAsset(name: string, x: number, y: number, z: number) -> (string?, string?)
Bake the single global reflection AND persist it to a faces6 .texture
asset (slot 0). Yields a few frames; call from a task/coroutine context.
Parameters
namestring— Destination asset identity (writes/source/<name>.texture/).xnumber— World X of the capture position.ynumber— World Y of the capture position.znumber— World Z of the capture position.
Returns (string?, string?) — The asset path on success, or (nil, errorMessage) on failure.
environment.captureToAsset("env_main", 0, 2, 0)
globals/environment/ensureSkyFallback
environment.ensureSkyFallback() -> boolean
Ensure the scene's sky is in the environment's sky slot: a reflective surface no probe covers then reflects the sky rather than black, and a partially covered one blends the shortfall against it. Queues a capture when the sky slot holds none, and re-arms the fallback when a capture is there but switched off. The engine's own state answers both questions, so everything that stands a sky up can call this and one capture is shared between them. Once captured, the slot follows the sky the scene draws on its own.
Returns boolean — True if a capture was queued, false if the sky slot already holds one.
environment.ensureSkyFallback()
globals/environment/loadFromAsset
environment.loadFromAsset(name: string) -> (boolean, string?)
Load a persisted global reflection asset into slot 0 and make it the active single reflection (one full-coverage probe).
Parameters
namestring— Source asset identity (reads/source/<name>.texture/).
Returns (boolean, string?) — True on success, or (false, errorMessage) on failure.
environment.loadFromAsset("env_main")
globals/environment/loadSlotFromAsset
environment.loadSlotFromAsset(name: string, slot: number) -> (boolean, string?)
Load a persisted faces6 .texture cubemap (written by
captureSlotToAsset) into reflection-probe slot WITHOUT re-rendering the
scene. Reads the 6 face PNGs from /source/<name>.texture/ and uploads them
into the slot's cube layers. How a persisted probe restores its baked
environment on reload.
Parameters
namestring— Source asset identity (reads/source/<name>.texture/).slotnumber— Reflection-probe slot (0-based).
Returns (boolean, string?) — True on success, or (false, errorMessage) on failure.
environment.loadSlotFromAsset("probe_lobby", 0)
globals/environment/setProbes
environment.setProbes(probes: { any }) -> boolean
Set the active reflection probes' blend data. probes is an array of
{ x, y, z, radius } (or { position = {x,y,z}, radius = r }); index i is
probe slot i. Surfaces blend the probe slots by proximity to these
positions, gathering the highest priority first — each rank takes the
coverage the ranks above it left, so a small interior probe ranked above a
large exterior one wins outright wherever it reaches full weight. Coverage
left over reflects the sky once captureSky has run. Queued for next frame.
Parameters
probes{ any }— Array of{ x, y, z, radius, priority? }, one per active probe slot.prioritydefaults to 0.
Returns boolean — True — the probe data was queued.
environment.setProbes({ { x = 0, y = 2, z = 0, radius = 12 } })
globals/environment/setSkyFallback
environment.setSkyFallback(active: boolean) -> boolean
Arm or disarm the sky fallback against the sky already captured, with no
recapture. Disarmed, reflections come from the probes alone. Arming is
refused while the sky slot holds no capture (captureSky fills it), since
an uncaptured slot reflects black; renderer.reflectionEnvironment()
reports whether the fallback ended up armed.
Parameters
activeboolean— Whether reflections fall back to the captured sky.
Returns boolean — True — the change was queued.
environment.setSkyFallback(false)
globals/environment/stateFromAsset
environment.stateFromAsset(identity: string) -> (boolean, string?)
Make a faces6 .texture cubemap the environment that cameras stating
it reflect. A camera rendering an isolated environment reflects only what
it states — never the world's sky or reflection probes — so this is what a
mirror or a pane of glass in its frame shows. The cube is stated under
identity, which is the name a camera's environmentMap gives it; stating
one already stated, from the same bytes, reads nothing. Called from a task,
it waits for faces whose bytes are still being fetched (the web build
fetches builtin images); called outside one, a face not yet fetched is
answered as missing.
Parameters
identitystring— The cube texture, by the identityasset.resolvetakes.
Returns (boolean, string?) — True once the environment is queued, or (false, errorMessage).
task.spawn(environment.stateFromAsset, "@builtin::textures.studio_environment")
modules/environment/capture
capture(x: number, y: number, z: number): boolean
Bake the scene into the environment from (x, y, z) as the single global
reflection (slot 0 + one full-coverage probe). Every PBR surface reflects it.
Queued — takes effect on the next frame. For multiple proximity-blended
probes use the reflectionProbe system instead.
Parameters
xnumber— World X of the capture position.ynumber— World Y of the capture position.znumber— World Z of the capture position.
environment.capture(0, 2, 0)
modules/environment/captureSky
captureSky(x: number?, y: number?, z: number?): boolean
Render the SKY alone into the environment's sky slot from (x, y, z) and
arm the sky fallback. A reflective surface no probe covers then reflects the
sky rather than black, and a partially covered one blends the shortfall
against it. The capture holds whatever the scene's sky draws — a gradient, a
physical atmosphere, a skybox material — with no geometry in it, so it stays
correct wherever the camera goes. Once captured, the slot follows the sky
the scene draws: a sky that changes is recaptured from the same position.
Queued — takes effect on the next frame.
Parameters
xnumber?(optional) — World X of the capture position. Defaults to 0.ynumber?(optional) — World Y of the capture position — the altitude a height-dependent atmosphere is sampled at. Defaults to 0.znumber?(optional) — World Z of the capture position. Defaults to 0.
environment.captureSky()
modules/environment/captureSlot
captureSlot(slot: number, x: number, y: number, z: number): boolean
Bake the scene into reflection-probe slot from (x, y, z).
Renders the FULL scene (geometry + sky) six times from that
point into that slot. Register the probe's position+radius via setProbes
so surfaces blend it by proximity. Queued — takes effect next frame.
Parameters
slotnumber— Reflection-probe slot (0-based).xnumber— World X of the capture position.ynumber— World Y of the capture position.znumber— World Z of the capture position.
environment.captureSlot(0, 0, 2, 0)
modules/environment/captureSlotToAsset
captureSlotToAsset(name: string, slot: number, x: number, y: number, z: number, timeoutFrames: number?): (string?, string?)
Bake the scene into reflection-probe slot from (x, y, z) AND persist
the 6 rendered faces into a faces6 .texture cubemap asset at
/source/<name>.texture/ (px/nx/py/ny/pz/nz PNGs + a cube.yaml sidecar).
Survives an engine restart and syncs like any other texture. Yields a few
frames while the bake + GPU readback complete; must be called from a
task/coroutine context (component hook, task.spawn, or execute).
Parameters
namestring— Destination asset identity (writes/source/<name>.texture/).slotnumber— Reflection-probe slot (0-based).xnumber— World X of the capture position.ynumber— World Y of the capture position.znumber— World Z of the capture position.timeoutFramesnumber?(optional) — Optional max frames to wait for the readback (default 900, past the frames the engine gives a readback before it gives up on one, so what ends the wait is the readback's own answer).
environment.captureSlotToAsset("probe_lobby", 0, 0, 2, 0)
modules/environment/captureToAsset
captureToAsset(name: string, x: number, y: number, z: number): (string?, string?)
Bake the single global reflection AND persist it to a faces6 .texture
asset (slot 0). Yields a few frames; call from a task/coroutine context.
Parameters
namestring— Destination asset identity (writes/source/<name>.texture/).xnumber— World X of the capture position.ynumber— World Y of the capture position.znumber— World Z of the capture position.
environment.captureToAsset("env_main", 0, 2, 0)
modules/environment/ensureSkyFallback
ensureSkyFallback(): boolean
Ensure the scene's sky is in the environment's sky slot: a reflective surface no probe covers then reflects the sky rather than black, and a partially covered one blends the shortfall against it. Queues a capture when the sky slot holds none, and re-arms the fallback when a capture is there but switched off. The engine's own state answers both questions, so everything that stands a sky up can call this and one capture is shared between them. Once captured, the slot follows the sky the scene draws on its own.
environment.ensureSkyFallback()
modules/environment/loadFromAsset
loadFromAsset(name: string): (boolean, string?)
Load a persisted global reflection asset into slot 0 and make it the active single reflection (one full-coverage probe).
Parameters
namestring— Source asset identity (reads/source/<name>.texture/).
environment.loadFromAsset("env_main")
modules/environment/loadSlotFromAsset
loadSlotFromAsset(name: string, slot: number): (boolean, string?)
Load a persisted faces6 .texture cubemap (written by
captureSlotToAsset) into reflection-probe slot WITHOUT re-rendering the
scene. Reads the 6 face PNGs from /source/<name>.texture/ and uploads them
into the slot's cube layers. How a persisted probe restores its baked
environment on reload.
Parameters
namestring— Source asset identity (reads/source/<name>.texture/).slotnumber— Reflection-probe slot (0-based).
environment.loadSlotFromAsset("probe_lobby", 0)
modules/environment/setProbes
setProbes(probes: { any }): boolean
Set the active reflection probes' blend data. probes is an array of
{ x, y, z, radius } (or { position = {x,y,z}, radius = r }); index i is
probe slot i. Surfaces blend the probe slots by proximity to these
positions, gathering the highest priority first — each rank takes the
coverage the ranks above it left, so a small interior probe ranked above a
large exterior one wins outright wherever it reaches full weight. Coverage
left over reflects the sky once captureSky has run. Queued for next frame.
Parameters
probes{ any }— Array of{ x, y, z, radius, priority? }, one per active probe slot.prioritydefaults to 0.
environment.setProbes({ { x = 0, y = 2, z = 0, radius = 12 } })
modules/environment/setSkyFallback
setSkyFallback(active: boolean): boolean
Arm or disarm the sky fallback against the sky already captured, with no
recapture. Disarmed, reflections come from the probes alone. Arming is
refused while the sky slot holds no capture (captureSky fills it), since
an uncaptured slot reflects black; renderer.reflectionEnvironment()
reports whether the fallback ended up armed.
Parameters
activeboolean— Whether reflections fall back to the captured sky.
environment.setSkyFallback(false)
modules/environment/stateFromAsset
stateFromAsset(identity: string): (boolean, string?)
Make a faces6 .texture cubemap the environment that cameras stating
it reflect. A camera rendering an isolated environment reflects only what
it states — never the world's sky or reflection probes — so this is what a
mirror or a pane of glass in its frame shows. The cube is stated under
identity, which is the name a camera's environmentMap gives it; stating
one already stated, from the same bytes, reads nothing. Called from a task,
it waits for faces whose bytes are still being fetched (the web build
fetches builtin images); called outside one, a face not yet fetched is
answered as missing.
Parameters
identitystring— The cube texture, by the identityasset.resolvetakes.
task.spawn(environment.stateFromAsset, "@builtin::textures.studio_environment")
typed/builtin//modules/api/engine/environment/environment/capture
environment.capture(x: number, y: number, z: number) -> boolean
Bake the scene into the environment from (x, y, z) as the single global
reflection (slot 0 + one full-coverage probe). Every PBR surface reflects it.
Queued — takes effect on the next frame. For multiple proximity-blended
probes use the reflectionProbe system instead.
Parameters
xnumber— World X of the capture position.ynumber— World Y of the capture position.znumber— World Z of the capture position.
Returns boolean — True — the capture was queued.
environment.capture(0, 2, 0)
typed/builtin//modules/api/engine/environment/environment/captureSky
environment.captureSky(x: number?, y: number?, z: number?) -> boolean
Render the SKY alone into the environment's sky slot from (x, y, z) and
arm the sky fallback. A reflective surface no probe covers then reflects the
sky rather than black, and a partially covered one blends the shortfall
against it. The capture holds whatever the scene's sky draws — a gradient, a
physical atmosphere, a skybox material — with no geometry in it, so it stays
correct wherever the camera goes. Once captured, the slot follows the sky
the scene draws: a sky that changes is recaptured from the same position.
Queued — takes effect on the next frame.
Parameters
xnumber(optional) — World X of the capture position. Defaults to 0.ynumber(optional) — World Y of the capture position — the altitude a height-dependent atmosphere is sampled at. Defaults to 0.znumber(optional) — World Z of the capture position. Defaults to 0.
Returns boolean — True — the sky capture was queued.
environment.captureSky()
typed/builtin//modules/api/engine/environment/environment/captureSlot
environment.captureSlot(slot: number, x: number, y: number, z: number) -> boolean
Bake the scene into reflection-probe slot from (x, y, z).
Renders the FULL scene (geometry + sky) six times from that
point into that slot. Register the probe's position+radius via setProbes
so surfaces blend it by proximity. Queued — takes effect next frame.
Parameters
slotnumber— Reflection-probe slot (0-based).xnumber— World X of the capture position.ynumber— World Y of the capture position.znumber— World Z of the capture position.
Returns boolean — True — the capture was queued.
environment.captureSlot(0, 0, 2, 0)
typed/builtin//modules/api/engine/environment/environment/captureSlotToAsset
environment.captureSlotToAsset(name: string, slot: number, x: number, y: number, z: number, timeoutFrames: number?) -> (string?, string?)
Bake the scene into reflection-probe slot from (x, y, z) AND persist
the 6 rendered faces into a faces6 .texture cubemap asset at
/source/<name>.texture/ (px/nx/py/ny/pz/nz PNGs + a cube.yaml sidecar).
Survives an engine restart and syncs like any other texture. Yields a few
frames while the bake + GPU readback complete; must be called from a
task/coroutine context (component hook, task.spawn, or execute).
Parameters
namestring— Destination asset identity (writes/source/<name>.texture/).slotnumber— Reflection-probe slot (0-based).xnumber— World X of the capture position.ynumber— World Y of the capture position.znumber— World Z of the capture position.timeoutFramesnumber(optional) — Optional max frames to wait for the readback (default 900, past the frames the engine gives a readback before it gives up on one, so what ends the wait is the readback's own answer).
Returns (string?, string?) — The asset path on success, or (nil, errorMessage) on failure.
environment.captureSlotToAsset("probe_lobby", 0, 0, 2, 0)
typed/builtin//modules/api/engine/environment/environment/captureToAsset
environment.captureToAsset(name: string, x: number, y: number, z: number) -> (string?, string?)
Bake the single global reflection AND persist it to a faces6 .texture
asset (slot 0). Yields a few frames; call from a task/coroutine context.
Parameters
namestring— Destination asset identity (writes/source/<name>.texture/).xnumber— World X of the capture position.ynumber— World Y of the capture position.znumber— World Z of the capture position.
Returns (string?, string?) — The asset path on success, or (nil, errorMessage) on failure.
environment.captureToAsset("env_main", 0, 2, 0)
typed/builtin//modules/api/engine/environment/environment/ensureSkyFallback
environment.ensureSkyFallback() -> boolean
Ensure the scene's sky is in the environment's sky slot: a reflective surface no probe covers then reflects the sky rather than black, and a partially covered one blends the shortfall against it. Queues a capture when the sky slot holds none, and re-arms the fallback when a capture is there but switched off. The engine's own state answers both questions, so everything that stands a sky up can call this and one capture is shared between them. Once captured, the slot follows the sky the scene draws on its own.
Returns boolean — True if a capture was queued, false if the sky slot already holds one.
environment.ensureSkyFallback()
typed/builtin//modules/api/engine/environment/environment/loadFromAsset
environment.loadFromAsset(name: string) -> (boolean, string?)
Load a persisted global reflection asset into slot 0 and make it the active single reflection (one full-coverage probe).
Parameters
namestring— Source asset identity (reads/source/<name>.texture/).
Returns (boolean, string?) — True on success, or (false, errorMessage) on failure.
environment.loadFromAsset("env_main")
typed/builtin//modules/api/engine/environment/environment/loadSlotFromAsset
environment.loadSlotFromAsset(name: string, slot: number) -> (boolean, string?)
Load a persisted faces6 .texture cubemap (written by
captureSlotToAsset) into reflection-probe slot WITHOUT re-rendering the
scene. Reads the 6 face PNGs from /source/<name>.texture/ and uploads them
into the slot's cube layers. How a persisted probe restores its baked
environment on reload.
Parameters
namestring— Source asset identity (reads/source/<name>.texture/).slotnumber— Reflection-probe slot (0-based).
Returns (boolean, string?) — True on success, or (false, errorMessage) on failure.
environment.loadSlotFromAsset("probe_lobby", 0)
typed/builtin//modules/api/engine/environment/environment/setProbes
environment.setProbes(probes: { any }) -> boolean
Set the active reflection probes' blend data. probes is an array of
{ x, y, z, radius } (or { position = {x,y,z}, radius = r }); index i is
probe slot i. Surfaces blend the probe slots by proximity to these
positions, gathering the highest priority first — each rank takes the
coverage the ranks above it left, so a small interior probe ranked above a
large exterior one wins outright wherever it reaches full weight. Coverage
left over reflects the sky once captureSky has run. Queued for next frame.
Parameters
probes{ any }— Array of{ x, y, z, radius, priority? }, one per active probe slot.prioritydefaults to 0.
Returns boolean — True — the probe data was queued.
environment.setProbes({ { x = 0, y = 2, z = 0, radius = 12 } })
typed/builtin//modules/api/engine/environment/environment/setSkyFallback
environment.setSkyFallback(active: boolean) -> boolean
Arm or disarm the sky fallback against the sky already captured, with no
recapture. Disarmed, reflections come from the probes alone. Arming is
refused while the sky slot holds no capture (captureSky fills it), since
an uncaptured slot reflects black; renderer.reflectionEnvironment()
reports whether the fallback ended up armed.
Parameters
activeboolean— Whether reflections fall back to the captured sky.
Returns boolean — True — the change was queued.
environment.setSkyFallback(false)
typed/builtin//modules/api/engine/environment/environment/stateFromAsset
environment.stateFromAsset(identity: string) -> (boolean, string?)
Make a faces6 .texture cubemap the environment that cameras stating
it reflect. A camera rendering an isolated environment reflects only what
it states — never the world's sky or reflection probes — so this is what a
mirror or a pane of glass in its frame shows. The cube is stated under
identity, which is the name a camera's environmentMap gives it; stating
one already stated, from the same bytes, reads nothing. Called from a task,
it waits for faces whose bytes are still being fetched (the web build
fetches builtin images); called outside one, a face not yet fetched is
answered as missing.
Parameters
identitystring— The cube texture, by the identityasset.resolvetakes.
Returns (boolean, string?) — True once the environment is queued, or (false, errorMessage).
task.spawn(environment.stateFromAsset, "@builtin::textures.studio_environment")