Skip to content
All lab

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.