Experiment · 2026
Archipelago
A GPU point cloud behind every page — and what it refuses to be
Thirty thousand points that resolve out of a drifting field into a chain of islands, in one draw call, without a React renderer — and the plain page for every device that should not run it.
What it is
The background of this site is a point cloud. On load, thirty thousand points drift in from a loose field and settle into a chain of islands on the right of the window, centred on a phone. At rest they breathe. They part around a pointer or a finger, lean toward the card or button under the cursor, loosen when a page leaves and resolve again when the next one arrives.
It is one geometry, one material and one draw call.
Why not react-three-fiber
For a single point cloud, a React reconciler for the scene earns nothing and
costs a second runtime against a hard budget: the three.js chunk has to stay
under 500KB, loaded lazily, after the page is already readable. So the canvas
is written against three.js directly, and three reaches the browser only
through one dynamic import.
The animation lives in the shader
Every point carries two positions — where it starts, in the drifting field,
and where it belongs, on an island — plus a random seed. The vertex shader
mixes between them against a single uniform, uProgress, and GSAP drives that
one number. The seed delays each point slightly, so the islands form as a wave
rather than snapping into place.
Nothing moves on the CPU per point. The page talks to the canvas through four
window events — scatter, gather, attract and showcase — so neither side
imports the other, and the page works the same when the canvas is absent.
When it does not run
The canvas is the enhancement; the plain page underneath is the default. It does not mount when:
- the visitor asked for reduced motion, in the OS or in the site's own accessibility panel
- the browser cannot give it a WebGL context
- Save-Data is on, or the connection reports 2g
- the device reports under 4GB of memory
Where it does run, it asks for the low-power GPU, caps the pixel ratio at 1.5, and drops to twelve thousand points on narrow screens. The people this site is for often open it on a mid-range Android, on mobile data, outside Metro Manila.
Watch it assemble
Behind every page the field sits faint, under the cards, so its resolve is easy to miss. The button on this note steps the page aside: everything else fades to 8% and stops taking input, the field comes up to near-full strength, and it resolves from nothing over five seconds, holds, then hands the page back over three.
The timing is only felt because it eases in and out. On the site's usual expo-out curve, a five-second resolve does most of its moving in the first second and then crawls — it reads as a snap and a stall, not as five seconds.
A finger, not a cursor
On a phone there is no pointer to part the islands, so a finger does it, on every page. That meant listening to touch events rather than pointer events. The moment a drag turns into a scroll, the browser takes the gesture and cancels the pointer stream — the effect would die a few pixels into almost every touch. Touch events keep arriving through the scroll.
The parting fades in where the finger lands and out where it lifts. Eased from where the cursor last was, it would have flown in from off-screen.
What it is not
It is not a map of the Philippines. The islands are procedural — a seeded north–south chain with a few outliers — so it reads as an archipelago without claiming to be a coastline. An inaccurate outline of a real country, on a site whose whole claim is getting the details right, is a bad trade for a background effect.
The upgrade path, if it is ever worth the day: sample points inside a public-domain outline at build time, keeping the same data shape.