Creative Coding

Three.js's Particle Ceiling Just Went From 50,000 to a Million — Here's What Actually Changed

With WebGPU now baseline across every major browser, Three.js's TSL shader system lets you write a shader once and target both WebGPU and WebGL without maintaining two codebases.

WebGPU officially reached Baseline status this January, meaning Chrome, Edge, Firefox, and Safari on both desktop and iOS now all ship it stable and on by default — closing a browser-support gap that’s shaped what creative coders could safely build for years. Three.js has been positioning for exactly this moment since r171, and the shape of that payoff is now visible in production numbers: compute-shader-driven particle systems that topped out around 50,000 instances under WebGL are now handling upward of a million under WebGPU.

Watch: Three.js: Introduction to WebGPU and TSL (YouTube)

The part that actually required engineering work

Swapping WebGLRenderer for WebGPURenderer has been a one-line change since r171, with automatic fallback to WebGL 2 on the roughly 5% of browsers that still need it — no bundler configuration, no polyfills required. But the harder problem was shaders: WebGPU and WebGL speak different shader languages (WGSL versus GLSL), which historically meant maintaining two separate shader codebases to support both. Three Shader Language, Three.js’s own answer to that problem, is a JavaScript-based shader authoring layer that compiles to both WGSL and GLSL from a single source — write the shader once, and it runs correctly on whichever renderer the browser ends up using.

Why that removes a real decision creative coders had to make

Before TSL matured, choosing WebGPU meant either accepting you’d lose users on unsupported browsers, or writing and maintaining a second GLSL shader path as a fallback — a real tax that pushed a lot of projects toward staying on WebGL by default, ceiling and all. A single shader source that targets both renderers removes that trade-off entirely: WebGPU’s ceiling becomes available without giving up WebGL’s reach, for roughly the cost of writing the shader the way you were already going to write it.

What the numbers are actually good for

March’s r184 release fixed per-frame object allocation issues that had been quietly limiting real-world performance gains even after the renderer swap, which matters more in practice than the headline particle count — a lot of generative and audio-reactive work lives or dies on consistent frame timing, not peak instance counts in a benchmark. For anyone maintaining a WebGL-era generative art project, this is the point where actually attempting the WebGPURenderer swap costs very little and has a real chance of paying off, rather than being an experimental detour.