Builtin Library
README.md
volumeDemos
Shared orchestration backend for the volumeDemos.package showcase
scenes. Owns the per-demo resource pack (3D texture, 2D render target,
two uniform buffers) and the auto-registered composite, exposing a
small public surface the demo scenes drive once per frame.
Exports
M.spawn({name, size, fillShader, fillUniformBytes}) -> ()— register a new demo pipeline. Creates the 3D volume, the 2D storage target, registers the per-demo fill shader, ensures the shared raymarcher is registered, and auto-installs the depth-aware composite.M.destroy(name) -> ()— release everythingspawncreated (texture + render target + buffers + composite registration).M.dispatchFill(name, fillUniforms) -> ()— packfillUniforms(Lua array of f32) into the demo's fill UBO and dispatch the fill shader against the volume.M.dispatchFrame(name, {camera, aabbMin, aabbMax, width, height, stepSize, maxSteps, alphaCutoff, densityGain, emissionGain}) -> ()— pack camera + raymarch params into the shared 40-float UBO and dispatch the raymarcher into the demo's render target.M.NAMES(name) -> {volume, rt, composite}— engine-side resource names for the demo (used by the.zvolviewer to bypass the helpers and upload voxels viacompute.writeFloatsTexture3Ddirectly).
Usage
-- From a demo scene at <pkg>/demo/<name>.scene/entrypoint.luau,
-- `...` climbs to the package root, then resolves volumeDemos.module:
local V = require("@builtin::systems.volumetrics.volumeDemos")
-- onLoad: spin up the pipeline.
V.spawn({
name = "smoke_plume",
size = { 96, 192, 96 },
fillShader = SMOKE_FBM_WGSL,
fillUniformBytes = 64,
})
-- update(dt): repaint the volume + raymarch into the RT.
V.dispatchFill("smoke_plume", { elapsed, density_amp, spread, ... })
V.dispatchFrame("smoke_plume", {
camera = cam.get(),
aabbMin = { -40, 0, -40 },
aabbMax = { 40, 160, 40 },
width = 1280, height = 720,
stepSize = 0.9, maxSteps = 240,
densityGain = 2.5, emissionGain = 1.0, alphaCutoff = 0.995,
})
-- onUnload: free GPU resources.
V.destroy("smoke_plume")
Notes
dispatchFramepacks 40 f32s into the raymarch UBO:[0..16)inv_view_proj (mat4 row-major),[16..19)aabb_min,[19..22)aabb_max,[22..23)step_size,[23..24)max_steps,[24..25)alpha_cutoff,[25..26)density_gain,[26..30)target_width/height + inv reciprocals,[30..31)emission_gain,[31..40)padding.- Pipeline state lives in module-locals keyed by
name— the same module instance can host many demos in parallel, but two scenes must not pick the samename. - Each demo scene supplies its own fill shader; the raymarcher is
shared (one shader name, one compiled pipeline). Replacing
fillShaderbetween frames is supported; replacing the raymarcher isn't (use the volumetrics package for that use case).