Drift - A journey from Earth to the edge of the Milky Way

Drift is a four-minute cinematic flight from Earth to the edge of the Milky Way, built with three.js and TypeScript. A small ship slaloms around every planet, dives through the gap between Saturn’s rings, crosses the Oort Cloud and finally turns to look back at the whole galaxy. Everything is procedural: there are no downloaded models, textures or audio. Planets, sky, ship and the ambient soundtrack are all generated at runtime.

How the maths works

  • Distances and time: each of the 14 landmarks has a real distance from Earth, from the Moon at 384,400 km to 76,000 light-years of route at the galaxy’s edge. Between landmarks, distance is interpolated logarithmically, d = expm1(lerp(log1p(a), log1p(b), t)), so the counters sweep smoothly across 15 orders of magnitude. Elapsed time is a light-speed clock: d / 299,792.458 km/s.
  • Flight path: a centripetal Catmull-Rom spline through waypoints that wrap about 150° around each planet. Journey progress is mapped to arc length with a monotone cubic (Fritsch–Butland), so speed stays continuous and the flight is identical at 1× or 8×. The ship banks according to the path’s curvature.
  • Camera: a chase camera on the smoothed heading. It swings wide and turns toward the nearest planet, with the effect weighted by a smoothstep of distance. The Sun’s direction shifts gradually between worlds so each one is lit three-quarters-on at closest approach.
  • Planets: surfaces are baked once on the GPU into cube maps, in 256-pixel tiles, so frames never stutter. Surface normals come from finite differences of the height field along the sphere’s tangents. Craters use a parabolic bowl smoothly blended with a raised rim and clamped to a flat floor, summed over octaves in a power-law size distribution.
  • Jupiter: the bands are traced backwards through a flow field, 28 steps per pixel. The field combines alternating jet streams, turbulence that can’t compress on the sphere (cross(p, ∇noise)), and elliptical vortices. That’s why the Great Red Spot winds the belts into spirals.
  • Atmospheres: ray-marched single scattering, Rayleigh plus Mie, with an analytic approximation for the light path toward the Sun.
  • Saturn: the ship’s orbit sits at exactly 1.985 Saturn radii. The ring plane is tilted about the mid-arc direction so the ship crosses it inside the Cassini Division. Rings and planet shadow each other through ray–plane and ray–sphere tests.
  • Sky: a baked Milky Way (dust lanes, nebulae, the Magellanic Clouds, Andromeda) plus 26,000 stars drawn as points so they stay pin-sharp.
  • Sound: an original generative score and flight sound design, synthesised with the Web Audio API.
1 Like

Interpolating the distance with log1p/expm1 is a neat way to sweep 15 orders of magnitude without the counter stalling at either end. Do you drive the ship’s progress along the spline with the same curve, or only the numbers? I’d guess the visuals want a different pacing than the counters.

Also curious about the generative score: over four minutes, how do you keep it from sounding like a loop? I synthesise a short space-travel transition with Web Audio on my site, and even at 2.6 seconds it took a few passes to stop sounding mechanical.