Reference
Quality levels
Four tiers, from integrated laptop GPUs to stills and trailers. A tier sets the grid resolution, the raymarch budget, the pressure iterations and the advection scheme.
const fire = await FireSystem.create({ renderer, scene, camera, quality: 'medium' }); // 'med' works too
fire.setQualityLevel('ultra');
fire.quality; // 'ultra'
fire.grid; // { nx: 80, ny: 120, nz: 80, cell: 0.05 } for a 4 × 6 × 4 m domain

campfire on low (40×60×40, semi-Lagrangian) and on high (64×96×64, MacCormack for the scalars), from the same camera.#At a glance
| Tier | Grid (4×6×4 m domain) | Voxels | Raymarch steps | Volume res | Jacobi | Advection |
|---|---|---|---|---|---|---|
low | 40×60×40 | 96K | 84 | 0.5× | 12 | Semi-Lagrangian |
medium | 52×78×52 | 211K | 112 | 0.6× | 18 | MacCormack (scalars) |
high | 64×96×64 | 393K | 140 | 0.85× | 24 | MacCormack (scalars) |
ultra | 80×120×80 | 768K | 190 | 1.0× | 32 | MacCormack (scalars + velocity) |
The volume resolution is relative to the canvas. On high-DPI screens it's capped at about 1.5× DPR pixels, and the TAA covers the rest. high is the default.
#Every field
QUALITY_LEVELS holds one object per tier:
| Field | low | medium | high | ultra | |
|---|---|---|---|---|---|
n | 40 | 52 | 64 | 80 | Grid cells across the domain's x size. y and z follow the domain's aspect |
steps | 84 | 112 | 140 | 190 | Raymarch steps across the domain diagonal |
scale | 0.5 | 0.6 | 0.85 | 1.0 | Volume render resolution relative to the canvas |
jacobi | 12 | 18 | 24 | 32 | Pressure iterations per step |
lsteps | 8 | 10 | 12 | 14 | Light-volume steps toward the key light |
fsteps | 6 | 8 | 8 | 10 | Light-volume steps toward the fire centroid |
maccormackState | off | on | on | on | Second-order advection of temperature and smoke |
maccormackVelocity | off | off | off | on | Second-order advection of velocity |
coolingScale | 1 | 1.9 | 1.9 | 1.9 | Compensates the lower numerical diffusion of MacCormack |
smokeFade | 0.1 | 0.6 | 0.6 | 0.6 | Smoke dissipation per second, compensated the same way |
label | LOW | MED | HIGH | ULTRA | Display name |
Fuel always uses first-order advection, even on MacCormack tiers. Its numerical diffusion is part of how the flame front is tuned, and sharpening it only makes the flames taller, not crisper.
#Custom tiers
The tiers are plain objects that are read when the grid is built. Edit one before create() or setQualityLevel():
import { QUALITY_LEVELS } from 'naturegl-fire';
QUALITY_LEVELS.high = { ...QUALITY_LEVELS.high, scale: 0.6, jacobi: 18 }; // cheaper high
fire.setQualityLevel('high'); // rebuild with it#Pick a starting tier
This is a rough guide rather than a benchmark. Profile on the hardware you target.
| Target | Tier |
|---|---|
| Integrated GPUs, phones | low |
| Mid-range laptops | medium |
| Apple M-series, discrete desktop GPUs at 1080p–1440p | high |
| Stills, trailers, posters | ultra |
The cost is mostly the grid (voxels × Jacobi iterations) plus the raymarch (screen pixels × scale² × steps). A smaller domain at the same n looks sharper for the same cost. The demo drops a tier by itself when it averages under 28 fps at start-up. Copy that logic from demo/main.js if you want the same thing.