Metaballs don’t draw overlapping spheres — they fill all of 3D space with a "density" value and extract a surface only where it crosses a threshold (isolation). The three/addons/objects/MarchingCubes.js this demo uses stores density on a grid (voxels) subdivided by resolution; each frame, mc.reset() clears the grid, then repeated calls to mc.addBall(x, y, z, strength, subtract) accumulate "add this much density here."
When two blobs get close, the grid cells between them sum both contributions, and the instant that sum crosses the threshold, the two surfaces merge into one — that’s the source of the classic liquid-like fuse-and-split metaball look. Calling mc.update() runs the marching cubes algorithm that turns that density grid into actual triangles — a classic technique that looks up, per grid cell, which edges the surface crosses via a lookup table.
addBall’s coordinates are in field space (roughly 0 to 1), and strength/subtract tune each blob’s "bulk" and how smoothly it blends when merging. Raising resolution smooths the surface but grows the cell count cubically, so per-frame cost climbs fast — around 32 is a practical ceiling for real-time animation.
When to use
Slime or liquid-metal characters, chemistry/molecule visualizations, or a logo animation that organically fuses together.