Builtin Library
README.md
environment Module
Environment / reflection capture — bake the scene into reflection-probe cube slots from world positions, persist them as faces6 .texture assets, set per-probe blend data so surfaces reflect the probes covering them, and capture the sky into its own slot as the fallback under them. Public Luau surface over the __environment Internal FFI namespace, auto-injected as _G.environment via the prelude.
Purpose
The generic "render the scene into a cubemap from a point" capability the reflection-probe system is built on. Captures are queued for the render system (which owns the live scene); captureSlotToAsset additionally yields a few frames while the GPU readback completes. Persisted cubes are faces6 .texture assets (px/nx/py/ny/pz/nz PNGs + a cube.yaml sidecar — see docs/specs/cubemap-textures.md §4 for the face convention).
For probe authoring use the higher-level reflectionProbe module; reach for environment when you need the raw per-slot primitives.
Usage
-- Register probe blend data: index i maps to cube slot i.
environment.setProbes({ { x = 0, y = 2, z = 0, radius = 12 } })
-- Bake slot 0 from a point (queued, next frame).
environment.captureSlot(0, 0, 2, 0)
-- Bake + persist to /source/probe_lobby.texture/ (yields; call from a
-- task/coroutine/execute context).
local path, err = environment.captureSlotToAsset("probe_lobby", 0, 0, 2, 0)
-- Restore a persisted cube into a slot WITHOUT re-rendering.
environment.loadSlotFromAsset("probe_lobby", 0)
-- Capture the sky alone into the fallback slot: a surface no probe covers
-- reflects the sky rather than black.
environment.captureSky()
Exports
environment.setProbes(probes) -> boolean— set active probes' blend data; array of{ x, y, z, radius, priority? }, index i → cube slot i, gathered highestpriorityfirstenvironment.captureSky(x?, y?, z?) -> boolean— render the sky alone into the fallback slot and arm it (queued)environment.setSkyFallback(active) -> boolean— arm/disarm the fallback against the sky already captured (arming is refused while the slot holds none)environment.captureSlot(slot, x, y, z) -> boolean— bake the scene into a slot from a point (queued)environment.captureSlotToAsset(name, slot, x, y, z, timeoutFrames?) -> (string?, string?)— bake + persist as afaces6.texture; yieldsenvironment.loadSlotFromAsset(name, slot) -> (boolean, string?)— upload a persisted cube into a slot without re-rendering
Back-compat single-global-reflection helpers (slot 0 + one full-coverage probe):
environment.capture(x, y, z) -> booleanenvironment.captureToAsset(name, x, y, z) -> (string?, string?)environment.loadFromAsset(name) -> (boolean, string?)