Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commitdf78e4f826

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 everything spawn created (texture + render target + buffers + composite registration).
  • M.dispatchFill(name, fillUniforms) -> () — pack fillUniforms (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 .zvol viewer to bypass the helpers and upload voxels via compute.writeFloatsTexture3D directly).

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

  • dispatchFrame packs 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 same name.
  • Each demo scene supplies its own fill shader; the raymarcher is shared (one shader name, one compiled pipeline). Replacing fillShader between frames is supported; replacing the raymarcher isn't (use the volumetrics package for that use case).