Skip to content

@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/particles

Quick 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);

Proprietary software. All rights reserved.