PBF

@three-blocks/coreWebGPU
new PBF()

Position Based Fluids (PBF) particle simulation optimized for GPU compute with optional spatial grid acceleration.

See also
  • SpatialGrid
Example
import { PBF } from '@three-blocks/core';
import { SphereGeometry, InstancedMesh, MeshStandardNodeMaterial } from 'three/webgpu';
import { storage, instanceIndex } from 'three/tsl';

const pbf = new PBF({
  count: 2000,
  is3D: true,
  domainDimensions: new THREE.Vector3(20, 20, 20),
  h: 1.2,
  viscosityMu: 0.15,
  useMatrices: true
});

// Create instanced mesh for rendering particles
const geometry = new SphereGeometry(0.3, 8, 8);
const material = new MeshStandardNodeMaterial();
const positionNode = storage(pbf.buffers.positions, 'vec3', pbf.particleCount);
material.positionNode = positionNode.element(instanceIndex);
const mesh = new InstancedMesh(geometry, material, pbf.particleCount);
// When useMatrices is enabled, you can feed instance matrices directly
mesh.instanceMatrix = pbf.buffers.instanceMatrices.value;
scene.add(mesh);

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

Properties

.sdfVolumeConstraint : SDFVolumeConstraint|null

Methods

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

setDomainFromObject#

setDomainFromObject(object : THREE.Object3D, options : Object) : this

Bind simulation domain to a Three.js object's world-space bounds. Particles will be constrained to the object's local space and follow its transforms.

Parameters
objectTHREE.Object3D
Target object (mesh or group).
optionsoptionalObject
Configuration options.
Default is {}.
  • paddingoptionalnumber | THREE.Vector3
    Extend domain bounds by padding.
    Default is 0.
  • autoUpdateoptionalboolean
    Update domain matrices every frame.
    Default is true.
  • simulationScaleoptionalnumber | THREE.Vector3
    Override domain scale for visualization.
    Default is null.
Returns
this

attachSpatialGrid#

attachSpatialGrid(grid : SpatialGrid) : this

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

Parameters
gridSpatialGrid
External SpatialGrid instance.
Returns
this

setSmoothingRadius#

setSmoothingRadius(radius : number) : this

Update the PBF smoothing kernel radius (h parameter). Recomputes kernel coefficients and syncs spatial grid cell size.

Parameters
radiusnumber
New smoothing radius (h).
Returns
this

setRestDensity#

setRestDensity(value : number|null|undefined) : this

Set rest density manually. Passing null/undefined re-enables auto rest density.

Parameters
valuenumber | null | undefined
Returns
this

setMass#

setMass(value : number) : this

Set particle mass. Recomputes auto rest density when enabled.

Parameters
valuenumber
Returns
this

setKernelScaleEnabled#

setKernelScaleEnabled(enabled : boolean) : this

Enable/disable automatic kernel radius scaling with domain transformations.

Parameters
enabledboolean
Whether to scale h with domain scale.
Returns
this

setGridUpdatePerIteration#

setGridUpdatePerIteration(enabled : boolean) : this

Control whether the spatial grid rebuilds each solver iteration or once per step.

Parameters
enabledboolean
When true, rebuild on every solver iteration (slower, more accurate).
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 kernel 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

syncSpatialGrid#

syncSpatialGrid() : this

Synchronize spatial grid configuration with current domain and kernel radius. Automatically called when domain or kernel changes.

Returns
this

step#

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

Advance the simulation by one frame using GPU compute passes. Executes: grid update → density → pressure → forces → interaction → integration.

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

attachGUI#

attachGUI(gui : Object, options : Object) : Object

Attach PBF parameters to a GUI for interactive tuning. Compatible with lil-gui, dat.gui, and Three.js Inspector.

Parameters
guiObject
GUI instance (e.g., new GUI() from lil-gui or renderer.inspector.createParameters()).
optionsoptionalObject
Configuration options.
Default is {}.
  • folderNameoptionalstring
    Name for the main folder.
    Default is 'PBF'.
  • openoptionalboolean
    Whether folders start open.
    Default is false.
Returns
Object — Object containing created GUI folders: { main, physics, simulation, domain, pointer }.

Type Definitions

PBFOptions#

count:number, is3D:boolean, domainDimensions:THREE.Vector3, mass:number, +25 more
Properties
countoptionalnumber
Number of particles to simulate.
Default is 5000.
is3Doptionalboolean
Enable 3D mode; false uses 2D kernels with single z-layer.
Default is true.
domainDimensionsoptionalTHREE.Vector3
Simulation domain size.
Default is new THREE.Vector3(32, 32, 32).
massoptionalnumber
Particle mass.
Default is 0.4.
hoptionalnumber
Smoothing kernel radius (PBF h parameter).
Default is 1.0.
restDensityoptionalnumber | null
Target rest density for the fluid. If null/undefined, it is auto-computed from mass, h, and kernel dimensionality (2D/3D).
Default is null.
pressureStiffnessoptionalnumber
Pressure force multiplier (legacy SPH compatibility).
Default is 100.0.
viscosityMuoptionalnumber
Legacy SPH viscosity value (kept for API parity, unused in solver).
Default is 0.12.
restitutionoptionalnumber
Coefficient of restitution for domain boundary collisions (0 = inelastic, 1 = elastic).
Default is 0.1.
maxSpeedoptionalnumber
Maximum allowed particle velocity magnitude.
Default is 15.0.
gravityoptionalTHREE.Vector3
Constant acceleration applied before constraint solving.
Default is new THREE.Vector3(0, -9.81, 0).
fixedTimeStepoptionalnumber | null
Fixed timestep (in seconds). Set to null to use variable dt based on the render loop.
Default is 1/60.
maxSubstepsoptionalnumber
Maximum number of fixed timesteps processed per frame (prevents spiraling after long pauses).
Default is 5.
maxFrameDeltaoptionalnumber
Maximum frame delta (in seconds) added to the accumulator to avoid huge jumps after tab switches.
Default is 0.1.
solverIterationsoptionalnumber
Number of constraint iterations per frame.
Default is 2.
lambdaEpsilonoptionalnumber
Relaxation epsilon added to the PBF lambda denominator.
Default is 50.0.
corrKoptionalnumber
Artificial pressure strength used in the sCorr term.
Default is 0.001.
corrNoptionalnumber
Exponent for the artificial pressure (sCorr) term.
Default is 4.0.
corrDeltaQMultiplieroptionalnumber
Fraction of the kernel radius used to compute the sCorr reference distance.
Default is 0.3.
debugoptionalboolean
Enable debug buffers and logging.
Default is false.
useDirectionoptionalboolean
Allocate buffers for smoothed particle directions (useful for oriented rendering).
Default is false.
scaleKernelWithDomainoptionalboolean
Scale smoothing radius proportionally with domain scale changes.
Default is true.
useSpatialGridoptionalboolean
Enable internal spatial grid acceleration (O(N) vs O(N²)).
Default is true.
useMatricesoptionalboolean
When true, writes per-instance transformation matrices to a storage buffer. Enables GPU culling with custom instanceMatrix on InstancedMesh (requires Three.js r182+).
Default is false.
gridUpdatePerIterationoptionalboolean
Rebuild the spatial grid each solver iteration (more stable, slower). When false, the grid updates once per simulation step.
Default is false.
spatialGridOptionsoptionalObject
Options passed to the internal SpatialGrid instance.
Default is {}.
spatialGridoptionalSpatialGrid
Attach a preconfigured SpatialGrid instance.
Default is null.
initialPositionsoptionalTHREE.StorageInstancedBufferAttribute
Optional external positions buffer to initialize particle positions from (e.g., from ComputeBVHSampler). Positions can be vec3 or vec4. Invalid positions (zero vectors) are automatically scattered to prevent spatial clustering.
Default is null.
sdfVolumeConstraintoptionalSDFVolumeConstraint
Optional SDF volume boundary constraint for complex boundaries.
Default is null.

PBFBuffers#

positions:THREE.InstancedBufferAttribute, velocities:THREE.InstancedBufferAttribute, densities:THREE.InstancedBufferAttribute, pressures:THREE.InstancedBufferAttribute, +5 more
Properties
positionsTHREE.InstancedBufferAttribute
Particle world positions (vec3).
velocitiesTHREE.InstancedBufferAttribute
Particle velocities (vec3).
densitiesTHREE.InstancedBufferAttribute
Computed particle densities (float).
pressuresTHREE.InstancedBufferAttribute
Stores PBF lambda values per particle (float).
pressureForcesTHREE.InstancedBufferAttribute
Accumulated position corrections (vec3).
prevPositionsTHREE.InstancedBufferAttribute
Previous-frame positions used to derive velocities (vec3).
viscosityForcesTHREE.InstancedBufferAttribute
Scratch buffer retained for compatibility (vec3).
prevVelocitiesoptionalTHREE.InstancedBufferAttribute
Previous frame velocities (optional, if useDirection enabled).
directionsoptionalTHREE.InstancedBufferAttribute
Smoothed directions (optional, if useDirection enabled).