gloop-sim
v1.0.2
Published
A particle swarm simulation and rendering library for running in the browser.
Maintainers
Readme
Gloop
Gloop is a TypeScript library for simulating swarms of particles in the browser. You could also call it a browser-based DEM simulator. It comes with some predefined physics models for the swarm, and you can define your own. The built-in models run both on the CPU and on the GPU via WebGPU, but implementing GPU support is optional for custom models.
The library also proves a declarative rendering API based on three.js for visualizing the simulation. It's designed to accommodate custom models and logic, so you can render things other than the particles themselves, like forces, velocities, fields or whatever else you can think of.
The documentation website has a live lab where you can try out the capabilities of Gloop without writing any code.
Installation
The package is published on npm as gloop-sim, with three as a required peer dependency. If you use pnpm, you can install the library like this:
pnpm add gloop-sim [email protected]Quick Start
Here's a swarm of three point masses connected to each other by springs, simulated on the CPU:
import { gloop } from "gloop-sim";
const swarm = await gloop.swarm({
particleCount: 3,
initializer: gloop.initializer.fixed({
positions: [
[0, 0, 0],
[1.5, 0, 0],
[0, 1, 0],
],
velocities: [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
],
}),
model: gloop.model.elasticNetwork({
masses: [1, 1, 1],
connections: [
{ between: [0, 1], restLength: 1 },
{ between: [0, 2], restLength: 1 },
{ between: [1, 2], restLength: Math.SQRT2 },
],
stiffness: 40,
springDamping: 1.5,
}),
integrator: gloop.integrator.semiImplicitEuler(),
backend: gloop.backend.cpu(),
});To step this simulation forward, you call advance with the desired time step in seconds. snapshot returns a copy of the swarm's state for inspection/visualization.
for (let step = 0; step < 30; step++) {
swarm.advance({ time: 1 / 60 });
}
const state = await swarm.snapshot();
console.log(state.time, state.particles.positions);Replacing gloop.backend.cpu() with gloop.backend.gpu() runs the same simulation on the GPU.
Simulation components
A swarm is built from four pluggable pieces:
| | |
| ---------------- | --------------------------------------------------------------------------------------- |
| Initializers | gloop.initializer provides the initial positions and velocities. |
| Models | gloop.model defines the forces acting on the particles. |
| Integrators | gloop.integrator advances the particle states in time. |
| Backends | gloop.backend runs the computation. cpu and gpu are currently supported. |
Rendering
gloop-sim/render visualizes the swarm with three.js. You first need to have an HTML canvas element to render something onto it.
const canvas = document.createElement("canvas");
document.body.append(canvas);Then, you can create a stage which will visualize the swarm.
import { view } from "gloop-sim/render";
const stage = await view.stage({
canvas,
// Currently only the GPU backend is supported for rendering.
backend: view.backend.gpu(),
clear: "#07090B",
pixelRatio: Math.min(devicePixelRatio, 2),
});Using stage.observe(swarm) you create a visualization for a specific swarm, which we refer to as a "scene". A scene has a fluent API for configuring the visualization.
In this case, we just want to visualize the particles as points of a specific color.
const scene = stage.observe(swarm).layers([
view.layer.particles({
from: view.sources.particles(),
shape: "point",
color: "#B8D8D8",
}),
]);Finally, we use requestAnimationFrame to animate the swarm in real-time. As before, you advance the simulation using swarm.advance. If you also want to render the new swarm state every time, you can call stage.render(scene) after every step.
function frame(): void {
swarm.advance({ time: 1 / 60 });
void stage.render(scene);
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);Documentation
| | | | ------------------------------------------------------------------------- | ----------------------------------------------------- | | Getting started | Installation, a first swarm, switching to the GPU | | Core concepts | Swarms, state and snapshots, and the pluggable pieces | | Rendering | Drawing a swarm with three.js | | API reference | Every exported function and type |
Development
Prerequisites:
- Node.js >= 20 with pnpm
- uv (for building the docs site via
uvx zensical) - A browser with WebGPU (for the lab and the GPU tests)
Get set up:
git clone https://gitlab.com/zurabm/gloop.git
cd gloop
pnpm installCommon tasks:
pnpm dev # run the lab locally
pnpm test # run the unit tests (vitest)
pnpm test:webgpu # run the GPU tests in a browser
pnpm test:coverage # unit tests with coverage
pnpm bench # benchmark both backends, report in generated/bench/
pnpm check # lint, spellcheck, typecheck, tests, build
pnpm docs:serve # serve the docs siteBenchmarks
pnpm benchThis opens Chromium with WebGPU enabled and runs a set of benchmarks. The run is archived to generated/bench/runs/, and the report is written to generated/bench/report.html with a text summary in generated/bench/summary.md.
To compare two archived runs, rebuild the report with one as the baseline:
pnpm bench:report --run generated/bench/runs/<new>.json --baseline generated/bench/runs/<old>.jsonSee CONTRIBUTING.md for the workflow and code style.
License
MIT, see LICENSE.
