SPH
new SPH(options : Object)Smoothed Particle Hydrodynamics (SPH) fluid simulation with spatial grid acceleration.
Features
- Pressure, viscosity, and gravity forces with configurable SPH kernels (Poly6, Spiky, Viscosity)
- Spatial grid acceleration (default) or naive O(N²) neighbor search
- 2D and 3D modes with appropriate kernel functions
- Domain attachment to Three.js objects for dynamic boundary transforms
- Pointer-based interaction for user-driven forces
- Optional direction storage for oriented particle rendering
Architecture
- Compute passes: density → pressure → forces (pressure + viscosity) → interaction → integration
- Spatial grid reduces neighbor search from O(N²) to O(N) via cell hashing
- Domain matrix transforms allow particles to follow moving/rotating objects
- Kernel radius auto-scales with domain transformations when
scaleKernelWithDomainis enabled
Constructor Parameters
optionsoptionalObjectDefault is
{}.countoptionalnumberNumber of particles to simulate.
Default is5000.is3DoptionalbooleanEnable 3D mode; false uses 2D kernels.
Default istrue.domainDimensionsoptionalTHREE.Vector3Simulation domain size (default: 32x32x32).massoptionalnumberParticle mass.
Default is0.4.hoptionalnumberSmoothing kernel radius.
Default is1.0.restDensityoptionalnumber|nullTarget rest density (auto-computed if null).
Default isnull.pressureStiffnessoptionalnumberPressure force multiplier.
Default is100.0.viscosityMuoptionalnumberViscosity coefficient.
Default is0.12.restitutionoptionalnumberBoundary collision restitution.
Default is0.1.maxSpeedoptionalnumberMaximum particle velocity.
Default is15.0.gravityoptionalTHREE.Vector3Gravity acceleration (default: -9.81 Y).fixedTimeStepoptionalnumber|nullFixed timestep (null for variable dt).
Default is1/60.maxSubstepsoptionalnumberMax fixed timesteps per frame.
Default is5.maxFrameDeltaoptionalnumberMax frame delta to avoid large jumps.
Default is0.1.debugoptionalbooleanEnable debug buffers.
Default isfalse.useDirectionoptionalbooleanAllocate direction buffers.
Default isfalse.scaleKernelWithDomainoptionalbooleanScale kernel with domain.
Default istrue.useSpatialGridoptionalbooleanEnable spatial grid acceleration.
Default istrue.useMatricesoptionalbooleanWrite per-instance matrices.
Default isfalse.spatialGridOptionsoptionalObjectSpatialGrid options.
Default is{}.spatialGridoptionalSpatialGridPreconfigured SpatialGrid.
Default isnull.initialPositionsoptionalTHREE.StorageInstancedBufferAttributeExternal positions buffer.
Default isnull.sdfVolumeConstraintoptionalSDFVolumeConstraintSDF boundary constraint.
Default isnull.- BVH boundary constraint.
Default isnull.
See also
- SpatialGrid
Example
import { SPH } from '@three-blocks/core';
import { SphereGeometry, InstancedMesh, MeshStandardNodeMaterial } from 'three/webgpu';
import { storage, instanceIndex } from 'three/tsl';
const sph = new SPH({
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(sph.buffers.positions, 'vec3', sph.particleCount);
material.positionNode = positionNode.element(instanceIndex);
const mesh = new InstancedMesh(geometry, material, sph.particleCount);
// When useMatrices is enabled, you can feed instance matrices directly
mesh.instanceMatrix = sph.buffers.instanceMatrices.value;
scene.add(mesh);
// Simulation loop
async function animate() {
await sph.step(renderer);
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
Properties
# .sdfVolumeConstraint : SDFVolumeConstraint|null
# .bvhVolumeConstraint : BVHVolumeConstraint|null
Methods
setDomainDimensions#
setDomainDimensions(dimensions : THREE.Vector3) : thisManually set the simulation domain dimensions. Updates UBOs and synchronizes the spatial grid.
Parameters
dimensionsTHREE.Vector3Returns
thissetDomainFromObject#
setDomainFromObject(object : THREE.Object3D, options : Object) : thisBind 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.Object3DoptionsoptionalObjectDefault is
{}.paddingoptionalnumber|THREE.Vector3Extend domain bounds by padding.
Default is0.autoUpdateoptionalbooleanUpdate domain matrices every frame.
Default istrue.simulationScaleoptionalnumber|THREE.Vector3Override domain scale for visualization.
Default isnull.
Returns
thisattachSpatialGrid#
attachSpatialGrid(grid : SpatialGrid) : thisAttach an external SpatialGrid instance for neighbor acceleration.
Rebuilds compute passes to use grid-accelerated lookups.
Parameters
gridSpatialGridReturns
thissetSmoothingRadius#
setSmoothingRadius(radius : number) : thisUpdate the SPH smoothing kernel radius (h parameter). Recomputes kernel coefficients and syncs spatial grid cell size.
Parameters
radiusnumberReturns
thissetRestDensity#
setRestDensity(value : number|null|undefined) : thisSet rest density manually. Passing null/undefined re-enables auto rest density.
Parameters
valuenumber | null | undefinedReturns
thissetMass#
setMass(value : number) : thisSet particle mass. Recomputes auto rest density when enabled.
Parameters
valuenumberReturns
thissetKernelScaleEnabled#
setKernelScaleEnabled(enabled : boolean) : thisEnable/disable automatic kernel radius scaling with domain transformations.
Parameters
enabledbooleanReturns
thisenableSpatialGrid#
enableSpatialGrid(options : Object) : thisCreate and attach an internal spatial grid for neighbor acceleration. Automatically configures grid based on current domain and kernel radius.
Parameters
optionsoptionalObjectSpatialGrid constructor.Default is
{}.Returns
thissetSpatialGridEnabled#
setSpatialGridEnabled(enabled : boolean, options : Object) : thisToggle spatial grid acceleration.
Parameters
enabledbooleanoptionsoptionalObjectenableSpatialGrid() if enabling.Returns
thisdetachSpatialGrid#
detachSpatialGrid() : thisDetach and dispose of the spatial grid, reverting to naive O(N²) neighbor search.
Returns
thissyncSpatialGrid#
syncSpatialGrid() : thisSynchronize spatial grid configuration with current domain and kernel radius. Automatically called when domain or kernel changes.
Returns
thisstep#
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.WebGPURendererReturns
Promise<void>attachGUI#
attachGUI(gui : Object, options : Object) : ObjectAttach SPH parameters to a GUI for interactive tuning. Compatible with lil-gui, dat.gui, and Three.js Inspector.
Parameters
guiObjectnew GUI() from lil-gui or renderer.inspector.createParameters()).optionsoptionalObjectDefault is
{}.folderNameoptionalstringName for the main folder.
Default is'SPH'.openoptionalbooleanWhether folders start open.
Default isfalse.
Returns
Object — Object containing created GUI folders: { main, physics, simulation, domain, pointer }.disposeGUI#
disposeGUI()Detach the SPH parameters GUI.
Type Definitions
SPHBuffers#
positions:THREE.InstancedBufferAttribute, velocities:THREE.InstancedBufferAttribute, densities:THREE.InstancedBufferAttribute, pressures:THREE.InstancedBufferAttribute, +4 more
Properties
positionsTHREE.InstancedBufferAttributevelocitiesTHREE.InstancedBufferAttributedensitiesTHREE.InstancedBufferAttributepressuresTHREE.InstancedBufferAttributepressureForcesTHREE.InstancedBufferAttributeviscosityForcesTHREE.InstancedBufferAttributeprevVelocitiesoptionalTHREE.InstancedBufferAttributeuseDirection enabled).directionsoptionalTHREE.InstancedBufferAttributeuseDirection enabled).