NEO/DAILY — today's near-Earth asteroids from NASA's live feed, every rock generated in shaders at runtime (Three.js + GSAP, no model files)

Live: https://neo-daily-landing.vercel.app/

Built with: three.js r185, GSAP, Vite — raw shaders, no post-processing, no model files

Every day NASA’s NeoWs feed lists the asteroids making their closest approach to Earth. NEO/DAILY turns that day’s feed into a scrollable register where each object gets its own generated WebGL body.

There are no meshes on disk. Every rock is a displaced sphere built in the vertex shader at load, seeded from the asteroid’s NASA ID — so the page is different every morning because the data is.

How a body is made

Nobody has imaged most of these rocks — for the majority we only have radar echoes and light curves, no shape model. So the silhouettes are generated, not observed, and I tried to be explicit about that rather than let it read as photography

What the data actually controls: the NASA object ID seeds the noise, so the same asteroid looks the same every time it comes back. Diameter nudges display scale, miss distance sets the order of the register, and the date decides which shape and palette each slot draws from.

The geometry is vertex displacement on a sphere — fbm for the mass, ridged fbm for the crags, and an inverted worley term to bite craters into it, then a per-shape asymmetry so nothing reads as a lumpy ball. Normals are recomputed from two tangent offsets and blended back toward radial, which keeps the terminator soft instead of faceted.

Surfaces are a single fragment shader with a switch over 17 treatments — cellular, banded, domain-warped, contoured, flecked. Each object picks one.

Motion

One body is pinned to the page and travels through the story. Each pass is a three-phase pinned sequence — arrival, a locked observation interval, then departure — and continued wheel input is absorbed by the locked phase, so a body can’t be scrolled past before you’ve actually looked at it. That was the part I rewrote most.

Eight motion scores rotate across passes: axial roll, high drop, corkscrew, slingshot, polar inversion, camera eclipse, pendulum drift, orbital rendezvous. The last section collects several bodies into one orbital group.

Notes

If the NeoWs feed is unreachable or rate-limited, the interface switches to a bundled archive sample and says so on screen rather than pretending it’s live.

Happy to go into the displacement or the pinning logic if anyone’s interested.

1 Like