webgl-particle-systems
WebGL Particle Systems
When to use this
- You need more than ~2,000 simultaneously animated elements and CSS/SVG will not cut it.
- The brief calls for particles forming text, logos, or organic flow-field motion.
- You want GPGPU (FBO ping-pong) simulation so the GPU does all position math per frame.
- Ambient background particles (dust, stars, bokeh) need to feel alive without tanking the main thread.
- Do NOT use this when the effect is a simple 2D canvas trail or grain overlay -- see
canvas-2d-performanceornoise-grain-textureinstead.
Mental model
A particle system is a big flat array of attributes (position, velocity, color, size, life) uploaded once to the GPU as a BufferGeometry. Each frame the vertex shader reads those attributes and decides where to place each point. The fragment shader draws each point as a textured quad (gl_PointSize sets the size, gl_PointCoord gives UV within the quad).
For CPU-driven systems you mutate the typed arrays on the JS side every frame and flag attribute.needsUpdate = true. This tops out around 50-100k particles depending on attribute count because the upload bandwidth becomes the bottleneck.
GPGPU systems move the simulation to the GPU entirely. Positions and velocities live in floating-point textures (RGBA32F). A simulation shader reads the previous frame's texture, computes forces, writes the new state to a second texture (ping-pong). The render pass samples that texture in the vertex shader to position each particle. This scales to 500k-1M+ particles because the CPU never touches per-particle data.
Curl noise is the standard flow-field technique: take a 3D noise field, compute its curl (cross product of partial derivatives), and use the resulting divergence-free vector field as velocity. Divergence-free means particles never clump or disperse -- they flow like smoke in still air.