INSPIRATION

Most 3D websites treat scroll as a gimmick — a few floating shapes that spin as you go down the page. I wanted scroll to actually mean something: what if scrolling was flying, and the destination was the literal edge of everything we can observe? COSMOS turns the scrollbar into the throttle for a cinematic camera flight that keeps zooming out in scale, chapter by chapter, until there's nowhere further to go. The finale interaction (hold-to-charge -> warp flythrough -> confetti) is a direct homage to Jam3's "FWA 100" (fwa100.jam3.com), an award-winning WebGL experience that used a similar hold-and-release structure.

WHAT IT DOES

COSMOS is a single-page, scroll-driven 3D experience with nine chapters, each a real jump in cosmic scale: departure from Earth, a pass by Mars, an asteroid belt leading to a ringed gas giant, a glowing particle nebula, a black hole that visibly bends light around it, a pull-back to see the Milky Way galaxy from outside, a further pull-back to the Cosmic Web (the largest structure in existence — galaxy clusters strung along filaments around vast dark voids), and finally the Cosmic Microwave Background itself — the oldest light in existence, and the literal edge of the observable universe. You can click on planets, the black hole, the galaxy, and the CMB to open info cards with real facts about them. At the very end, press-and-hold a circular button to charge a warp jump: the camera flies at a portal while the field of view stretches for a warp-speed feel, then bursts into a physics-driven confetti celebration.

HOW I BUILT IT

Everything runs on Three.js, loaded straight from a CDN via an import map — no build step, no bundler, no npm install. The camera path is built from hand-placed keyframes fed into two Catmull-Rom splines (position + look-at target), so scroll progress produces one continuous, smooth flight instead of jump-cuts, all the way from planet-scale to universe-scale. Stars use a custom vertex/fragment shader so each one twinkles independently. Planets get a Fresnel "atmosphere glow" shader for a soft rim-light. The black hole chapter uses a custom ShaderPass that warps the screen around the event horizon's projected screen position — real gravitational-lensing-style distortion. The Milky Way is a 14,000-particle procedural four-arm logarithmic spiral, color-graded from a warm core to a cool rim. The Cosmic Web is built from random-walk filament chains of glowing cluster nodes connected by faint lines. The CMB is a canvas-generated mottled noise texture in the classic CMB palette, rendered on the inside of a large sphere so the camera sits "inside" it. The finale's hold-to-charge button is an SVG ring whose stroke-dashoffset animates with hold duration; on full charge, a state machine takes over the camera, stretches the FOV from 60 to 115 degrees, streams radial particle "speed lines," and finishes with 140 instanced tetrahedra (confetti) driven by simple per-particle gravity/rotation/fade math.

CHALLENGES I RAN INTO

Getting the atmosphere glow shader right took a couple of iterations — my first version lit up the center of each planet instead of just the rim. I had a bug where the scroll-content overlay was silently blocking all click events on the 3D canvas underneath it (pointer-events cascading down from a parent container), which made "click-to-explore" look broken even though the raycasting logic was correct. When I extended the journey to galaxy/cosmic-web/CMB scale, I hit a script-order bug — those new objects were referenced by the camera's keyframe array before they were actually defined, since I'd appended the new code below the keyframes instead of above. And after building the warp finale, I found the camera would snap back to the scroll position the instant the warp finished, because my state machine didn't have an explicit "done, hold steady" branch. Each of these was caught by actually testing the interaction in a real browser rather than assuming the code was correct.

WHAT'S NEXT

Real planet/galaxy textures instead of flat colors and canvas noise, a mini "warp speed" transition between every chapter (not just the finale), more cosmic-web filaments and clickable clusters, and a loading bar tied to real asset-loading progress.

TECH USED

Three.js (r160), custom GLSL shaders (twinkling stars, Fresnel atmosphere glow, gravitational lensing ShaderPass, warp streak particles), UnrealBloomPass post-processing, InstancedMesh for the confetti burst, vanilla HTML/CSS/JS (no framework, no build tool), Web Audio API for optional ambient sound.

Share this project:

Updates

Submission history