Noureddine RAMDI / Efficient particle system rendering with three.quarks in TypeScript

Created Sat, 23 May 2026 20:41:14 +0000 Modified Sat, 23 May 2026 20:41:27 +0000

Alchemist0823/three.quarks

Particle systems are the backbone of visual effects in 3D graphics, enabling everything from smoke and fire to magic spells and weather phenomena. Managing these systems efficiently, especially when rendering many particles, is a common challenge for developers working with WebGL and Three.js. The three.quarks library tackles this problem by offering a batched particle system renderer designed for flexibility and performance in TypeScript environments.

What three.quarks offers and how it works

At its core, three.quarks is a TypeScript library built on top of Three.js, the popular 3D rendering framework for the web. It provides a set of tools to create, configure, and render particle systems in a way that maximizes GPU efficiency.

The architecture centers around the concept of a BatchedRenderer which manages multiple particle systems together. This batch renderer reduces the number of draw calls by grouping particles from different systems, an important optimization for WebGL where draw call overhead can be a bottleneck.

Particle systems themselves are highly configurable with parameters like lifespan (duration), looping behavior, initial particle properties such as speed and size, color, emission rates, and shapes. The library ships with predefined value types like ConstantValue and IntervalValue to define these parameters flexibly and consistently.

Emitting shapes, such as points, are abstracted through emitters like PointEmitter. For rendering, three.quarks supports different modes including BillBoard rendering, where particles always face the camera, a typical approach for sprites and particle effects.

The stack is purely TypeScript and Three.js, making it accessible to web developers familiar with these technologies. The library depends on Three.js materials and textures, allowing seamless integration with existing Three.js scenes.

Technical strengths and design tradeoffs

The standout feature of three.quarks is its batch rendering approach. By aggregating particle systems under a single renderer, it cuts down on GPU state changes and draw calls. In WebGL, this can translate to smoother frame rates and the ability to handle more particles simultaneously.

The design is modular: users create particle systems with clear configurations, then add them to the batch renderer which handles updating and rendering in the animation loop. This separation of concerns improves maintainability and composability.

Another strength is the use of typed value wrappers (ConstantValue, IntervalValue) which simplify parameter management and reduce boilerplate. This pattern also allows for future extensibility, such as adding dynamic or animated parameter sources.

However, the tradeoff is the complexity this layering adds. Users must grasp the abstraction layers of batch renderer, particle systems, emitters, and value types to use the library effectively. For simple use cases, this might feel heavyweight compared to straightforward particle sprite systems.

The library also targets WebGL contexts, so it inherits the platform’s limitations: GPU resource constraints, browser compatibility issues, and potential performance variability across devices.

Under the hood, the code is surprisingly clean and well-structured for a graphics library. The use of TypeScript brings type safety, which is a boon for developers integrating complex particle effects into larger applications.

Quick start

Getting started with three.quarks is straightforward if you have a Three.js scene ready. Installation and usage are as simple as:

npm install three.quarks

Then, in your JavaScript or TypeScript code:

import * as THREE from 'three';
import {
    BatchedRenderer,
    ParticleSystem,
    ConstantValue,
    IntervalValue,
    ConstantColor,
    PointEmitter,
    RenderMode
} from 'three.quarks';

// 1. Create the batch renderer (manages all particle systems)
const batchRenderer = new BatchedRenderer();
scene.add(batchRenderer);

// 2. Define your particle system
const particles = new ParticleSystem({
    duration: 2,
    looping: true,
    startLife: new IntervalValue(1, 2),
    startSpeed: new ConstantValue(5),
    startSize: new IntervalValue(0.1, 0.3),
    startColor: new ConstantColor(new THREE.Vector4(1, 1, 1, 1)),
    maxParticle: 100,
    emissionOverTime: new ConstantValue(20),
    shape: new PointEmitter(),
    material: new THREE.MeshBasicMaterial({
        map: yourTexture,
        transparent: true
    }),
    renderMode: RenderMode.BillBoard
});

// 3. Add to scene and renderer
scene.add(particles.emitter);
batchRenderer.addSystem(particles);

// 4. Update in your animation loop
function animate() {
    const delta = clock.getDelta();
    batchRenderer.update(delta);
    renderer.render(scene, camera);
    requestAnimationFrame(animate);
}

This example shows the typical flow: setup a batch renderer, configure a particle system with desired parameters and material, add it to the scene and renderer, then update the batch renderer in your animation loop. The use of textures and materials from Three.js makes it flexible for custom visuals.

Verdict

three.quarks is a practical and well-structured library for TypeScript developers working with Three.js who need performant, flexible particle systems. Its batch rendering design is effective for managing multiple particle systems with reduced GPU overhead.

It is best suited for projects that require medium to complex particle effects and where performance matters, such as games, interactive visualizations, or simulations running in the browser.

The learning curve can be a bit steep if you’re new to Three.js or particle system abstractions, but the clean API and modular design reward the investment.

Limitations include its dependency on WebGL and Three.js, and the inherent complexity of managing particle lifecycles and rendering states. It might be overkill for very simple or one-off effects.

Overall, three.quarks is worth considering if you want a robust, composable particle library that integrates tightly with Three.js and leverages TypeScript’s type safety for better DX.


→ GitHub Repo: Alchemist0823/three.quarks ⭐ 937 · TypeScript