Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit3bb1da2647

README.md

volumetrics

Volumetric (3D-texture) rendering, end to end, in one package. Built entirely on the engine's generic compute.* GPU primitives — no Rust changes are needed to author new volumetric content.

Layout

AssetIdentityRole
Volume.component@builtin::systems.volumetrics.VolumeAttach a 3D voxel texture to an entity; raymarches it through the entity's transform AABB.
VolumetricSky.component@builtin::systems.volumetrics.VolumetricSkySingleton procedural cloud layer with TAA.
ParticipatingMedium.component@builtin::systems.volumetrics.ParticipatingMediumMark an entity as fog/smoke/dust that attenuates the light passing through it.
mediaTransmittance.module@builtin::systems.volumetrics.mediaTransmittanceLight-space optical-depth map: the registry, the settings, and the basis the map is built in.
mediaShadow.renderFeature@builtin::systems.volumetrics.mediaShadowBuilds the optical-depth map and attenuates each surface by the density in front of it.
volume.module@builtin::systems.volumetrics.volumeBuilders (noise/sphere/box/wrap) + the .zvol header reader + occupancy + brick paging + the per-entity raymarch dispatch.
VolumeSequence.component@builtin::systems.volumetrics.VolumeSequencePlay an open volume sequence through an entity's transform AABB.
volumeSequence.module@builtin::systems.volumetrics.volumeSequenceA run of .zvol frames streamed through a fixed ring of resident volumes.
volumeDemos.module@builtin::systems.volumetrics.volumeDemosShared pipeline for the showcase scenes (fill + emissive raymarch + composite).
volumetricSky.module@builtin::systems.volumetrics.volumetricSkyCloud volume + raymarch + TAA + composite orchestration.
shaders/*.shader@builtin::systems.volumetrics.shaders.*volume_raymarch, volume_pages, volume_pack, cloud_noise[_v3/_v5], cloud_raymarch[_v3/_v4/_v5], cloud_taa.
importers/vdb_to_zvol.importer(auto-discovered).vdb → dense .zvol via the openvdb WASM plugin (procedural fallback when the plugin isn't loaded).
presets/cumulus_default.preset@builtin::systems.volumetrics.cumulus_defaultCanonical full VolumetricSky weather preset.
demo/*.scene@builtin::systems.volumetrics.demo.*sdf_solids, smoke_plume, nebula, godrays, zvol_viewer, sky.

Path convention — fully-qualified builtin identities

Every intra-package reference uses the asset's fully-qualified builtin identity, the same convention every other builtin package follows:

local Volume = require("@builtin::systems.volumetrics.volume")
local Sky    = require("@builtin::systems.volumetrics.volumetricSky")
local V      = require("@builtin::systems.volumetrics.volumeDemos")
-- shader identities, e.g. asset.resolve("@builtin::systems.volumetrics.shaders.volume_raymarch")

Qualified identities are caller-independent: they resolve identically from a module, a scene entrypoint, or a component. Caller-relative (.sibling) requires are deliberately avoided here because the component runtime caller identity is @builtin::components.<Name>, so a .sibling require from a component resolves against the wrong root. (An earlier revision of this package used a ~volumetrics package-root alias for relocatability; that alias is not resolvable on current main, so the package uses qualified identities throughout.)

Usage

-- Per-entity volume. The component resolves the name through `Volume.get`,
-- so a volume paged into a brick pool renders from the pool under the same
-- name:
local Volume = require("@builtin::systems.volumetrics.volume")
local cloud = Volume.noise({ name = "cloud", size = 64, scale = 4 })
cloud:buildSparse({ brickSize = 8 })
cloud:releaseDense()
entity(id).component.add("Volume", { volumeName = "cloud", density = 6.0 })

-- Procedural sky:
local sky = entity.spawn("sky")
sky.component.add("VolumetricSky", {})
preset.apply("cumulus_default", { entity = sky.id, component = "VolumetricSky" })

-- VDB import: drop a `.vdb` into the VFS; the importer writes a `.zvol`
-- alongside it. Load it with the zvol_viewer demo scene.

-- Animated run: one `.zvol` per frame, played through a bounded ring.
local Seq = require("@builtin::systems.volumetrics.volumeSequence")
Seq.open({ name = "plume", frames = framePaths, resident = 3, fps = 24 })
entity(id).component.add("VolumeSequence", { sequenceName = "plume", density = 6.0 })

Plugin dependency

The VDB importer delegates real OpenVDB parsing to the openvdb plugin in the builtin library, @builtin::plugins.openvdb. Without the plugin the importer falls back to a deterministic procedural torus so the pipeline stays functional.