Reference
API reference
Everything exported from src/index.js and build/index.js. The types are in build/*.d.ts.
import {
FireSystem, FireEmitter, FireObstacle,
PRESETS, getPresetParams, QUALITY_LEVELS, normalizeQuality,
DEFAULT_PARAMS, BURST_TYPES, EMITTER_DEFAULTS,
patchReflectiveMaterial, createTeepeeGeometry, sampleSurface,
blackbodyRGB, kelvinToColor,
} from 'naturegl-fire';World units are metres. The sim temperature T runs from about 0 to 1.7, and gas glows from about 0.34 (flameThreshold).
#FireSystem
FireSystem.create(options): Promise<FireSystem>static asyncBuilds the solver, the screen pipeline, the lights and the embers, and loads the initial preset. new FireSystem(options) does the same synchronously. Throws if the renderer lacks WebGL2 or EXT_color_buffer_float.
| Option | Type | Default | |
|---|---|---|---|
renderer | THREE.WebGLRenderer | — | Required. WebGL2 + EXT_color_buffer_float |
scene | THREE.Scene | — | Required. render() draws it under the fire, and the lights are added to it |
camera | THREE.Camera | — | Required. Perspective or orthographic |
quality | 'low', 'medium' ('med'), 'high', 'ultra' | 'high' | See Quality levels |
domain | { center, size } (Vector3 or array) | (0, 3, 0), (4, 6, 4) | The simulation box. Cells are cubes of size.x / n |
preset | name, preset object or null | 'campfire' | null starts empty |
meshes | Record<string, Object3D> | {} | Mesh slots that presets refer to (logs, shape) |
addLights | boolean | true | Add fireLight and fillLight to scene |
#Frame
fire.update(dt): voidmethodRuns every offscreen GPU pass: mesh-emitter splat, obstacle mask, the solver, the light volume, embers, and the fire probe every third frame. It also advances the auto-burst clock and updates the lights. dt is in seconds and clamped to 1/120–1/30 s per step. Call it once per frame, before render() or composite().
fire.render(target?): voidmethodThe full screen pipeline: your scene into a colour + depth target, embers, the volume raymarch, TAA, the bilateral composite with heat haze, then bloom, exposure and ACES to sRGB. Writes to target, or to the canvas when it's null (the default). Replaces renderer.render(scene, camera), and restores the renderer's target, clear colour and autoClear afterwards. See Rendering.
fire.composite(inputColor, inputDepth, target?, camera?): voidmethodFor your own pipeline: raymarches the fire against your linear-HDR colour and DepthTexture and writes scene × transmittance + fire, with heat haze, to target, in linear HDR. No bloom, no tone mapping and no embers (add fire.embers to your scene). The alpha of inputColor is read as 1 − reflectivity. camera defaults to fire.camera. See composite().
fire.resize(width?, height?): voidmethodSets the internal targets to a drawing-buffer size, by default the renderer's. render() and composite() call it for you when the size changes.
fire.dispose(): voidmethodRemoves the lights and embers from their parents, removes every emitter and frees every GPU resource.
#Presets and parameters
fire.loadPreset(preset, options?): FireSystemmethodLoads a preset by name or object. Replaces the emitters, obstacles and auto-burst. Params the preset doesn't list reset to DEFAULT_PARAMS. Options: origin (world position, overrides the preset's), meshes (slots to register), keepFluid (don't clear the fluid). See Presets.
fire.getParams(): FirePresetmethodThe current state as a JSON-safe preset: label, origin, params, emitters (relative to origin), autoBurst, obstacles and the camera hint. Numbers are rounded to 3 decimals. Feed it back to loadPreset().
fire.setParams(partial): FireSystemmethodMerges into params. There's no easing.
fire.setQualityLevel(level): voidmethodSwitches tier and rebuilds the grid. Emitters and obstacles survive, but the fluid restarts from empty.
fire.reset(): voidmethodClears the fluid, the embers and the TAA history.
#Sources, obstacles and bursts
fire.addEmitter(options): FireEmittermethodAdds a fire source and returns its handle. Up to 8 point, sphere or box emitters are simulated at once, plus any number of mesh emitters. See FireEmitter and Emitters.
fire.removeEmitter(emitter)fire.clearEmitters()methodRemoves one emitter, or all of them.
fire.addObstacle(options): FireObstaclemethodAdds a solid sphere or box the gas flows around. Moving it pushes the gas. Up to 4 are simulated. fire.removeObstacle(o) removes one.
fire.burst(position, type?, strength?): FireSystemmethodA one-shot burst of fuel, heat, smoke and pressure. type is 'fireball' (the default) or 'explosion', and strength defaults to 1. It scales fuel, smoke, radial push and expansion, and the radius grows with ∛strength. Up to 4 bursts are active at once, and a new one replaces the oldest. Calls onBurst. See Explosions and fireballs.
fire.explode(position, strength?)fire.fireball(position, strength?): FireSystemmethodShorthand for burst(position, 'explosion', strength) and burst(position, 'fireball', strength).
fire.setOrigin(position): FireSystemmethodMoves the preset anchor. Emitters created by loadPreset() move with it, and so does the auto-burst.
fire.setWind(strength, direction?): FireSystemmethodSets params.wind (m/s) and, optionally, params.windDirection (array or Vector3).
fire.setLighting({ sunDirection?, sunColor?, sunIntensity?, ambient? }): FireSystemmethodThe key light and ambient used for smoke scattering and self-shadowing, for example from a sky system. sunIntensity (default 1) multiplies sunColor. See Match the scene lighting.
fire.setMesh(name, mesh): FireSystemmethodRegisters a mesh for a preset slot, for example 'logs' or 'shape'.
fire.bottomCenter(out?): Vector3methodWorld position of the domain's floor centre, which is what preset origins are relative to.
#Properties
| Property | Type | |
|---|---|---|
fireLight | THREE.PointLight | Shadow-casting, near the flame base. Colour from the blackbody ramp, intensity from the flame volume. See Fire light |
fillLight | THREE.PointLight | Higher in the plume, no shadows |
fireState | { position, power, temperature, kelvin, smoke, burn } | The GPU probe, read back asynchronously every 3 frames. power is the flame volume in m³ |
embers | THREE.Points | 4096 GPU particles advected by the gas |
params | FireParams | Live parameters. See Fire parameters |
emitters, obstacles | arrays | The handles |
origin | Vector3 | Preset anchor (world) |
autoBurst | { type, every, offset, strength } | null | Periodic bursts. Assign to change or stop them |
onBurst | (type, position, strength) => void | Called for every burst, including auto-bursts |
domain | { min, size, center } | The simulation box (world) |
grid | { nx, ny, nz, cell } | Grid size of the current tier |
quality, presetName | string, string | null | |
sceneTarget, depthTexture | The scene target render() uses | |
meshes | Record<string, Object3D> | Registered mesh slots |
#FireEmitter
Returned by addEmitter(). Every field is live. The defaults are EMITTER_DEFAULTS.
| Field | Default | |
|---|---|---|
type | 'sphere' | 'point', 'sphere', 'box' or 'mesh' |
position | (0, 0.5, 0) | Vector3, world. For a built-in mesh geometry it places the invisible geometry |
radius | 0.3 | m. Point emitters default to 0.15. On a box it's the edge softness (default 0.12) |
size | (0.5, 0.5, 0.5) | Box size, m |
fuel | 60 | Fuel per second |
temperature | 1.3 | Ignition temperature of what it injects (about 0.8 smoulders, 1.4 is a torch, 1.6 a blast) |
smoke | 0.6 | Smoke per second (× params.smoke) |
flicker | 0.5 | 0 = steady, 1 = fully noise-gated |
velocity | (0, 1.6, 0) | Jet velocity, m/s |
velocityBlend | 0.3 | How strongly the gas is forced to velocity (0.95 = hard jet) |
inheritVelocity | 0 | Fraction of the emitter's measured motion added to velocity |
embers, emberOffset, emberRadius | 0.5, (0, 0.2, 0), 0.3 | Ember spawn rate and region |
enabled | true | |
motion | Measured world velocity (read-only, m/s) |
Mesh emitters take these options too:
| Option | Default | |
|---|---|---|
mesh | Emit from this THREE.Mesh's surface. It follows the mesh's world matrix | |
geometry | 'teepee' | A BufferGeometry, or 'teepee', 'torusKnot', 'torus' or 'icosahedron', when there's no scene mesh |
samples | 16000 | Surface samples |
weight | 0.6 | Strength |
push | 7 | Outward and upward push along the normals |
filter | (p, n) => boolean, a surface sample filter | |
points | Pre-sampled surface points (a BufferGeometry with position and normal). Skips sampling |
emitter.set(props)emitter.remove()emitter.getWorldPosition(out)emitter.toJSON(origin?)methodset() assigns several fields at once, and vectors accept arrays. remove() detaches the emitter. toJSON() returns a preset emitter descriptor, with the position relative to origin when you pass one.
#FireObstacle
Returned by addObstacle().
| Field | Default | |
|---|---|---|
type | 'sphere' | 'sphere' or 'box' |
position | (0, 2.5, 0) | World |
radius | 0.6 | Sphere radius, m |
size | (1, 1, 1) | Box size, m |
enabled | true | |
velocity | Measured from its motion each frame (clamped to 6 m/s). Moving it pushes the gas |
Methods: set(props), remove(), toJSON().
#Constants
| Export | |
|---|---|
PRESETS | Record<string, FirePreset>: campfire, torch, jet, plume, fireball, explosion, mesh |
getPresetParams(name) | A deep clone of a preset. Throws on an unknown name |
QUALITY_LEVELS | Per-tier settings. Edit before create() or setQualityLevel() for custom tiers |
normalizeQuality(q) | Maps 'med' to 'medium', and throws on unknown tiers |
DEFAULT_PARAMS | Every FireParams default |
BURST_TYPES | fireball and explosion burst archetypes. See Burst types |
EMITTER_DEFAULTS | The defaults of addEmitter() |
#Helpers
patchReflectiveMaterial(material, { strength? }): { value }functionMakes a MeshStandardMaterial or MeshPhysicalMaterial write alpha = 1 − wetness, where smooth texels count as wet. The fire then reflects in it. Returns the strength uniform (default 1). See Wet-floor reflections.
createTeepeeGeometry(): BufferGeometryfunctionThe campfire's log geometry, useful as visible logs.
sampleSurface(geometry, count, filter?): BufferGeometryfunctionA surface point cloud with normals, which is what mesh emitters splat.
blackbodyRGB(kelvin): [r, g, b, Y]kelvinToColor(kelvin, color): ColorfunctionThe blackbody ramp on the CPU: normalised linear sRGB plus relative luminance, or written into a THREE.Color.