Boids

@three-blocks/coreWebGPU
new Boids(options : Object)

GPU-accelerated boids flocking simulation with spatial grid optimization.

Features

  • Classic boids rules: separation, alignment, cohesion with configurable weights
  • Spatial grid acceleration (default) or naive O(N²) neighbor search
  • 2D and 3D modes with boundary reflection
  • Pointer-based interaction for user-driven steering
  • Optional instanced mesh with automatic orientation from velocities
  • Phase tracking for wing flapping animation sync
  • Supports initialization from external samplers (e.g., ComputeBVHSampler)
  • GPU culling support with custom instanceMatrix (Three.js r182+)

Architecture

  • Compute passes: GPU init → velocity (neighbor influence) → position (integration)
  • Spatial grid reduces neighbor search from O(N²) to O(N) via cell hashing
  • Three behavioral zones: separation (repel), alignment (match velocity), cohesion (attract)
  • Node-based instancing helper provides per-boid transform matrices for rendering
import { Boids, ComputeBVHSampler, ComputeInstanceCulling, instanceCullingIndex } from '@three-blocks/core';
import { ConeGeometry, InstancedMesh, MeshPhysicalNodeMaterial } from 'three/webgpu';

// Advanced: Initialize from ComputeBVHSampler with GPU culling (Three.js r182+)
const sampler = new ComputeBVHSampler(sdfGenerator, renderer, count);
await sampler.compute();

const boids = new Boids({
  count,
  is3D: true,
  domainDimensions: new THREE.Vector3(100, 100, 100),
  separation: 0.035,
  alignment: 0.04,
  cohesion: 0.03,
  useRelativeParameters: true,
  useMatrices: true, // Enable instance matrices for GPU culling
  initialPositions: sampler.positionsBuffer // Initialize from sampler
});

// Create mesh with custom instanceMatrix for GPU culling
const geometry = new ConeGeometry(0.15, 0.6, 4);
const material = new MeshPhysicalNodeMaterial({ color: 0xffffff });
const mesh = new InstancedMesh(geometry, material, count);
mesh.instanceMatrix = boids.buffers.instanceMatrices.value;
mesh.frustumCulled = true;
scene.add(mesh);

// Use culling index in material
const instanceCulling = new ComputeInstanceCulling(mesh, renderer);
const culledIndex = instanceCullingIndex(instanceCulling);
material.colorNode = boids.buffers.velocities.element(culledIndex).xyz.length()...;
Constructor Parameters
optionsoptionalObject
Configuration options.
Default is {}.
  • countoptionalnumber
    Number of boids to simulate (rounded up to next power of 2).
    Default is 16384.
  • is3Doptionalboolean
    Enable 3D mode; false restricts movement to a 2D plane.
    Default is true.
  • domainDimensionsoptionalTHREE.Vector3
    Simulation domain bounds (default: 800x800x800).
  • speedLimitoptionalnumber
    Maximum velocity as ratio of domain size when useRelativeParameters=true.
    Default is 0.3.
  • separationoptionalnumber
    Separation distance as ratio of domain size.
    Default is 0.025.
  • alignmentoptionalnumber
    Alignment distance as ratio of domain size.
    Default is 0.03.
  • cohesionoptionalnumber
    Cohesion distance as ratio of domain size.
    Default is 0.08.
  • useRelativeParametersoptionalboolean
    Interpret distances as ratios of domain size.
    Default is true.
  • debugoptionalboolean
    Enable debug buffers and logging.
    Default is false.
  • useDirectionoptionalboolean
    Allocate buffers for smoothed velocity directions.
    Default is false.
  • useMatricesoptionalboolean
    Write per-instance transformation matrices to storage buffer.
    Default is false.
  • timeScaleoptionalnumber
    Scales simulation speed.
    Default is 1.0.
  • fixedTimeStepoptionalnumber | null
    Fixed timestep (seconds). Null for variable dt.
    Default is 1/60.
  • maxSubstepsoptionalnumber
    Maximum fixed substeps per frame.
    Default is 5.
  • maxFrameDeltaoptionalnumber
    Maximum frame delta to avoid large jumps.
    Default is 0.1.
  • useSpatialGridoptionalboolean
    Enable spatial grid acceleration.
    Default is true.
  • spatialGridOptionsoptionalObject
    Options for internal SpatialGrid.
    Default is {}.
  • spatialGridoptionalSpatialGrid
    Attach a preconfigured SpatialGrid.
    Default is null.
  • initialPositionsoptionalTHREE.StorageInstancedBufferAttribute
    External positions buffer.
    Default is null.
  • sdfVolumeConstraintoptionalSDFVolumeConstraint
    SDF volume boundary constraint.
    Default is null.
  • bvhVolumeConstraintoptionalBVHVolumeConstraint
    BVH volume boundary constraint.
    Default is null.
See also
  • SpatialGrid
Example
import { Boids } from '@three-blocks/core';
import { ConeGeometry, InstancedMesh, MeshStandardNodeMaterial } from 'three/webgpu';
import { instanceIndex } from 'three/tsl';

// Basic usage with material positionNode
const boids = new Boids({
  count: 5000,
  is3D: true,
  domainDimensions: new THREE.Vector3(200, 200, 200),
  separation: 0.025,
  alignment: 0.03,
  cohesion: 0.08,
  useRelativeParameters: true,
  useMatrices: true
});

// Create instanced mesh for rendering
const geometry = new ConeGeometry(0.5, 1.5, 4);
const material = new MeshStandardNodeMaterial();
material.positionNode = boids.instanceMatrix().element( instanceIndex );
const mesh = new InstancedMesh(geometry, material, boids.particleCount);
// When useMatrices is enabled, you can feed instance matrices directly
mesh.instanceMatrix = boids.buffers.instanceMatrices.value;
scene.add(mesh);

// Simulation loop
function animate() {
  boids.step(renderer);
  renderer.render(scene, camera);
  requestAnimationFrame(animate);
}

Properties

.sdfVolumeConstraint : SDFVolumeConstraint|null

.bvhVolumeConstraint : BVHVolumeConstraint|null

Methods

attachSpatialGrid#

attachSpatialGrid(grid : SpatialGrid) : this

Attach an external SpatialGrid instance for neighbor acceleration. Rebuilds compute passes to use grid-accelerated neighbor lookups.

Parameters
gridSpatialGrid
External SpatialGrid instance.
Returns
this

enableSpatialGrid#

enableSpatialGrid(options : Object) : this

Create and attach an internal spatial grid for neighbor acceleration. Automatically configures grid based on current domain and zone radius.

Parameters
optionsoptionalObject
Options forwarded to SpatialGrid constructor.
Default is {}.
Returns
this

setSpatialGridEnabled#

setSpatialGridEnabled(enabled : boolean, options : Object) : this

Toggle spatial grid acceleration.

Parameters
enabledboolean
Enable (true) or disable (false) spatial grid.
optionsoptionalObject
Options passed to enableSpatialGrid() if enabling.
Returns
this

detachSpatialGrid#

detachSpatialGrid() : this

Detach and dispose of the spatial grid, reverting to naive O(N²) neighbor search.

Returns
this

setDomainDimensions#

setDomainDimensions(dimensions : THREE.Vector3) : this

Manually set the simulation domain dimensions. Updates UBOs and synchronizes the spatial grid.

Parameters
dimensionsTHREE.Vector3
New domain dimensions.
Returns
this

syncSpatialGrid#

syncSpatialGrid() : this

Synchronize spatial grid configuration with current zone radius and domain. Automatically called when parameters change.

Returns
this

step#

step(renderer : THREE.WebGPURenderer) : Promise<void>

Advance the simulation by one frame using GPU compute passes. Executes: grid update (if enabled) → GPU init (first frame) → velocity → position.

Parameters
rendererTHREE.WebGPURenderer
WebGPU renderer instance.
Returns
Promise<void>

Type Definitions

BoidsBuffers#

positions:THREE.InstancedBufferAttribute, velocities:THREE.InstancedBufferAttribute, phase:THREE.InstancedBufferAttribute, prevVelocities:THREE.InstancedBufferAttribute, +1 more
Properties
positionsTHREE.InstancedBufferAttribute
Boid world positions (vec3).
velocitiesTHREE.InstancedBufferAttribute
Boid velocities (vec3).
phaseTHREE.InstancedBufferAttribute
Flapping animation phase (float).
prevVelocitiesoptionalTHREE.InstancedBufferAttribute
Previous frame velocities (optional, if useDirection enabled).
directionsoptionalTHREE.InstancedBufferAttribute
Smoothed directions (optional, if useDirection enabled).