What it does
A GPU emitter is an object in your 2D world, with a position, a layer and a depth, and it can follow another object. Its particles live in a ring pool on the graphics card: a compute pass on WebGPU, or transform feedback on WebGL2, moves every one of them each frame, and a single instanced draw puts them on screen in the emitter's own place among the sprites. A snowstorm on a back layer falls behind the world; a nova on a front layer bursts over it. When more are born than the pool holds, the oldest are recycled, so the pool never grows.
It uses the same ideas as particles-2d in a subset sized for the GPU: random ranges for speed, angle, lifespan,
size, rotation and spin, a birth zone, a colour ramp of up to four stops, a fade, twinkle, stretch along the
velocity, gravity and drag. Forces are data, up to eight per emitter: acceleration, drag, curl noise, attract,
vortex, orbit and gusting wind, and the list can be changed while the effect runs.
The idea that makes weather work is the wrap box. Give an emitter a wrap size and it folds every particle back
into a box centred on itself; let the emitter follow the camera and a bounded pool reads as snow or rain over a world
of any size, at the same cost wherever the player goes.
Features
- Up to two million particles — a pool from 64 to two million, 65,536 by default, recycled as a ring.
- Drawn in its place — the emitter sorts with the sprites on its layer, so a field can sit behind or in front of the world.
- Live control —
rate,burst(n),pausedand the wholeconfig, forces included, can change while it runs. - Birth zones — a point, a circle with an inner radius, a rectangle or a ring, with an option to launch outward from the centre for shells and novas.
- Forces as data — acceleration, drag, curl noise, attract, vortex, orbit with a spring, and wind with gusts.
- Wrap box — particles fold round the emitter, so a pool that follows the camera covers an unbounded world.
- Look over life — a colour ramp of up to four stops, an end size that shrinks or grows, a fade over the whole life or its final part, twinkle, spin and stretch along the velocity.
- Additive by default — the blend that stays correct for an unsorted pool.
Good for
- Weather over a scrolling 2D world — snow, rain or dust that follows the camera and wraps round it.
- Space games — dense star fields and drifting dust behind the action.
- Big explosions and novas — a radial burst of tens of thousands of glowing particles.
- Dense ambient backgrounds — swirling curl-noise fields and vortices behind a menu or a level.
- Arcade light shows — glowing fields pulled into a vortex or round an attractor, with bloom on top.
Make it yours
Every emitter is a GpuEmitterConfig: its pool size, its rate, where particles are born and how they move, look
and fade. Ranges are [min, max] or a single number, force positions are relative to the emitter, and a seed fixes
the spawn hash. The config stays live on the handle, so you can push a vortex into config.forces when a black hole
opens, raise the rate as a storm builds or burst fifty thousand at once.
Two very different uses: a gentle snowfall on the back layer, following the camera with a wrap box the size of the screen, curl noise and a gusting wind; and a nova on the front layer, a pool with no rate and a single radial burst, coloured from white through orange to red as it fades.
A quick look
A snowstorm that follows the camera, wraps round it and changes while it runs:
const snow = game.gpuParticles.emitter({
follow: camTarget, layer: 'back', capacity: 200000, rate: 20000,
emitZone: { kind: 'rect', w: 900, h: 600 }, wrap: { w: 900, h: 600 },
angle: [80, 100], speed: [30, 60], lifespan: [6, 9], size: [2, 5], color: '#ffffff', fade: 0.2,
forces: [{ kind: 'curl', strength: 60, scale: 0.01, speed: 0.3 }, { kind: 'wind', x: 20, y: 0, gust: 0.8, gustSpeed: 0.2 }],
frame: 'particle:soft', blend: 'add',
});
snow.gpu.rate = 5000;
snow.gpu.burst(50000);
Works with
particles-2d— for the hero effects that need sub-emitters, death zones, callbacks and exact replays.particle-textures— the soft, spark and other particle pictures that need no image files.post-bloom— makes additive fields glow.particles-gpu-3d— GPU particle fields for 3D worlds.
Good to know
- It simulates on each rendered frame's time step, not the fixed game step, so it is not deterministic and draws
nothing headless; use
particles-2dwhere an effect must replay exactly. - There are no sub-emitters, death zones, bounds, callbacks or sorting, and normal blending draws in pool order, so overlaps can be wrong: keep it additive.
- The draw covers the whole pool whatever is alive, so size
capacityto the effect rather than to "lots". - Eight forces, four colour stops and one frame per emitter; the
alivecount is an estimate, not a readback. - A lost graphics device restarts every pool empty.






