Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit65083fe8f2

README.md

volumetricSky

Orchestration backend for the VolumetricSky.component. Owns the GPU resources the cloud layer needs (cloud volume, raymarch render target, ping-pong TAA history pair, post-process composite) and exposes a small public surface the component drives every frame.

Exports

  • M.spawn(opts?) -> id — spawn the singleton sky entity, or configure the one already standing, and return its id. Every weather parameter (coverage, sunDir, sunColor, sunIntensity, windSpeed, …) is settable at the top level or inside a preset sub-table; every VolumetricSky component field (shaderVariant, cloudSize, taaBlendAlpha, …) by its own name; name names the entity. Parameters left out keep their current values. An option that names neither raises, listing both sets, and leaves no entity behind. A weather parameter takes the shape its default carries — a number, or an array of that many numbers — and a value of another shape raises naming the parameter.
  • M.configure(opts) -> boolean — apply those same weather parameters and component fields to the sky already standing. Returns false when none has been spawned.
  • M.defaultPreset() -> table — a fresh copy of the weather configuration a sky spawned with no options carries. The copy is the caller's to edit.
  • M.destroy() -> () — release every resource spawn created.
  • M.fillClouds(noiseParams) -> boolean: bake the cloud volume with the active cloud_noise_* shader when what it holds is not what noiseParams describe, and return whether this call baked. A change to a shaping parameter, the colour, the seed, the size, the variant or the render device bakes at once, and a write to the noise shader's shader.wgsl or bindings.yaml bakes once the program it compiles is resident; a change to the wind alone bakes at most noiseParams.noiseRegenRate times per second (default M.DEFAULT_NOISE_REGEN_RATE, 0 = every call the wind moved) on noiseParams.clock (default getTime()). noiseParams is the flat table produced by VolumetricSky.component's snapshotNoiseParams().
  • M.volumeBakes() -> number: how many times the cloud volume has been baked since the module loaded.
  • M.dispatchRaymarch(renderParams, viewport) -> () — dispatch the active cloud_raymarch_* shader, blend with history via the TAA pass, and write into the composite target. renderParams is the flat table from snapshotRenderParams().
  • M.find() -> id? — return the id of the active VolumetricSky entity, or nil if none has been spawned by M.spawn.
  • M.despawn() -> () — despawn the entity M.spawn minted (does NOT free GPU resources — call M.destroy() for that).
  • M.setCoverage(c) / M.setDensity(g) / M.setSun(dir, color, intensity?) / M.setWind(v) — convenience setters that route through the active component's public fields.
  • M.reprojectionDepthNdc(camPos, fwd, aabbMin, aabbMax, near, far) -> number — the NDC z the TAA pass carries history through, taken from where the cloud stands along the centre view ray. A point at range d travels translation / d across the screen, so this is what keeps a translating camera's history landing on the part of the picture the cloud moved to.

Usage

-- The component drives this module automatically. Direct M.* use is
-- rare; the canonical entry point is attaching VolumetricSky to an
-- entity (or loading a preset and passing it to component.add):
local sky = entity.spawn("sky")
sky.component.add("VolumetricSky", {})

-- Driving the layer by hand instead, a frame at a time. Each dispatch
-- creates the resources it needs at the size its own arguments name —
-- the cloud volume from `noiseParams.cloudSize / cloudHeight`, the
-- render target and composite from the viewport:
local Sky = require("@builtin::systems.volumetrics.volumetricSky")
Sky.fillClouds(noiseParams)
Sky.dispatchRaymarch(renderParams, { width = 1280, height = 720 })

Notes

  • shaderVariant selects which compute shader pair (cloud_noise_v3 + cloud_raymarch_v3 / cloud_noise + cloud_raymarch_v4 / cloud_noise_v5 + cloud_raymarch_v5). The module resolves the variant strings to absolute identities — relative paths don't work from a module body (the chunkname retains an .init segment that throws off the rsplit-to-parent step in resolve_relative_dot).
  • The cloud volume + history pair are RGBA16F — 256×128×256 ≈ 32 MiB VRAM. Drop to 192/96 via cloudSize / cloudHeight if tight.
  • The TAA pass is a single compute dispatch blending current sample with the previous frame's RT through the history pair. Set taaBlendAlpha = 1.0 to disable while still going through the same code path (useful for benchmarking).
  • All public setters write through to VolumetricSky.component's public fields, which means they replicate as Sync if the component is sync-enabled. Tweaks survive scene reloads as long as the same entity is alive.
  • SkyPreset and its defaults are declared here, and the component declares its preset field from them. M.spawn / M.configure read that same key set to tell a weather parameter from a component field, so a parameter added to the preset reaches the schema and the option routing in one edit.