@web-engine-dev/particles
GPU-accelerated particle system for WebGPU/WebGL with a CPU fallback.
Features
- GPU Simulation via compute shaders (WebGPU)
- CPU Fallback when compute is unavailable
- Emitter Shapes: point, sphere, hemisphere, cone, box, circle, edge, mesh
- Modules: color/size/rotation/velocity/force over lifetime, noise
- Burst + Continuous Emission, plus rate-over-distance
- Async Compute with sync helpers
- Memory Budgeting for large scenes
Installation
bash
npm install @web-engine-dev/particles
# or
pnpm add @web-engine-dev/particlesQuick Start
typescript
import { createParticleSystemFromDevice, ParticleEmitter } from '@web-engine-dev/particles';
import { createDevice } from '@web-engine-dev/renderer';
const { device } = await createDevice({ canvas });
const system = createParticleSystemFromDevice(device);
await system.initialize();
const fire = new ParticleEmitter({
maxParticles: 5000,
lifetime: { min: 0.5, max: 1.5 },
startSpeed: { min: 2, max: 5 },
startSize: { min: 0.2, max: 0.6 },
emission: { rateOverTime: 200 },
shape: { type: 'cone', angle: 20, radius: 0.5 },
colorOverLifetime: {
color: {
colorStops: [
{ time: 0, color: { r: 1, g: 0.9, b: 0.3, a: 1 } },
{ time: 1, color: { r: 0.3, g: 0.1, b: 0.1, a: 0 } },
],
},
},
});
system.createEmitter(fire.config);
function frame(dt: number) {
system.update(dt);
system.render(camera, viewMatrix, projectionMatrix);
}If you want a CPU-only simulation (e.g. Canvas2D visualization), you can explicitly force it:
typescript
import { ParticleSystem } from '@web-engine-dev/particles';
const system = new ParticleSystem({ backend: 'cpu' });Emission Examples
Burst
typescript
const explosion = new ParticleEmitter({
maxParticles: 500,
lifetime: 0.6,
startSpeed: { min: 5, max: 15 },
startSize: { min: 0.1, max: 0.2 },
emission: {
rateOverTime: 0,
bursts: [{ time: 0, count: { min: 100, max: 200 } }],
},
looping: false,
});Rate over distance
typescript
const trails = new ParticleEmitter({
maxParticles: 2000,
lifetime: 0.8,
startSpeed: 0,
startSize: 0.1,
emission: { rateOverDistance: 12 },
});Async Compute (WebGPU)
typescript
system.update(deltaTime);
// do other CPU work
await system.sync();
await system.renderAsync(camera, viewMatrix, projectionMatrix);