The Spaghettification
The story behind The Spaghettification
Inspired by Spaghettification on Wikipedia
Built with Three.js · ShaderMaterial Points (90k particles) · Custom GLSL · UnrealBloomPass · Screen-space gravitational lensing
Techniques Per-particle tidal deformation in vertex shader · Doppler color shift from radial velocity · Photon-sphere ring · Chromatic Einstein ring · Background ray-bending around the cursor
Direction You are the singularity. Pull a star toward your gravity and watch what survives the approach.
Result A drifting star elongates into an incandescent thread as it nears the cursor, wraps around the event horizon, and feeds a luminous accretion disk that cannot be undone
The Story
When a star wanders too close to a supermassive black hole, the difference in gravitational pull between its near side and far side becomes catastrophically steep. The side facing the singularity is pulled harder than the side facing away. The star is stretched along the radial axis and squeezed perpendicular to it — a process the physicist Stephen Hawking memorably called spaghettification. The star unspools into a thin, incandescent streamer that wraps around the hole. Some of it is consumed; some is flung outward at relativistic speed in a polar jet. Astronomers see this signature flare across the sky every few years — a “tidal disruption event,” the slow, then sudden undoing of something that used to be a sun.
What’s strange about spaghettification is that it doesn’t involve any contact, any heat, any chemistry. It’s just gradient. The star is unmade by the difference in pull from one side of itself to the other. Geometry alone is the executioner. A perfectly uniform field — even an infinitely strong one — would do nothing, because every part of the star would accelerate identically. It is the change in the field across the star’s body that destroys it. The black hole reaches in, and the star comes apart of its own accord.
This experience puts you on the wrong side of that equation.
The Take
A black sphere sits in space, ringed by a photon orbit and a faint chromatic Einstein ring. Background stars warp around it where light has been bent. Off to one side, a small luminous cluster — your star — drifts, designated with a real Gaia/HD/Hipparcos-style catalog name and a mass given in solar units.
The cursor is the singularity. There’s no UI, no crosshair, no slider. Where you point, the gravitational well lives. Move close to the star and it begins to elongate. The stretching is real — every particle in the cluster computes its own tidal displacement in the vertex shader, scaled by the inverse square of the cursor distance. As you approach, the spherical body of the star draws out into a teardrop, then a streamer, then a long thread that wraps around the void.
Once the streamer crosses the event horizon, that material is consumed. Not deleted, exactly — it joins an accretion disk that orbits the cursor and can’t be returned to the star. The HUD on the left edge tells the story without commentary: remaining falls, accreted rises, the tidal index climbs as you close in. Pull the cursor back and what’s left of the star tries to relax — but the lost mass is permanently in orbit, hot and silent.
The arc of discovery is short and brutal: curiosity, then realization, then an attempt to undo what cannot be undone. Click anywhere to release a fresh star — a new designation, a new mass — and try again with a softer touch.
The Tech
90,000 particles, one vertex shader
The star is a single THREE.Points mesh with ~90k vertices (35k on mobile). Each vertex carries two custom attributes: a rest position inside a unit ball (biased toward center for stellar density), and a per-particle seed in [0,1] used for randomization.
The vertex shader runs the entire deformation per particle. It computes the unit vector from the star’s center to the cursor (the tidal axis), decomposes the rest position into components along and perpendicular to that axis, and stretches/squeezes each component:
float tidal = clamp(uTidalScale / (starDist * starDist + 0.18), 0.0, 8.0);
float along = dot(aRest, tidalAxis);
vec3 perp = aRest - tidalAxis * along;
vec3 deformed = perp / (1.0 + tidal * 0.55)
+ tidalAxis * along * (1.0 + tidal * 4.2 + tidal*tidal * 0.6);
The squeeze factor compresses the perpendicular profile while the stretch factor pulls particles along the tidal axis. The quadratic term means stretching grows non-linearly as the star approaches — a real spaghettification curve.
Doppler color shift
Each particle’s color is biased by its radial velocity component projected onto the camera view vector. Particles flowing toward the camera get blue-shifted; those flowing away get red-shifted. The streamer therefore has a subtle chromatic gradient as you watch it move — the leading edge wraps around the singularity in cool blue, the trailing edge recedes in red. For accreted particles, the Doppler comes from their orbital velocity around the cursor.
Screen-space gravitational lensing
The black hole itself is rendered by a fullscreen fragment shader that runs behind the particles. Instead of true ray-tracing, it uses a fast 2D approximation: for each pixel, it computes the radial offset from the cursor and bends the apparent background-star position by an angle proportional to k/r (the standard weak-lensing deflection). Where this bending crosses zero, the Einstein ring lights up — split into chromatic R/G/B rings for visual interest. A thin photon-sphere ring sits just outside the event horizon. The starfield itself is procedural — three layers of low-discrepancy noise, each star drawn as a Gaussian core in its grid cell.
Bloom — gently
UnrealBloomPass with a high threshold (0.65) so only the hottest particles bleed light. Strength is moderate (0.45). Without bloom the streamer reads as a cold line of dots; with too much bloom the structure disappears into a white blob. The threshold is the most important knob — it preserves the per-particle texture of the star while letting the bright accretion ring glow.
Tone mapping
LinearToneMapping, not ACES. ACES crushes the dim background stars and the limb-darkened space around the event horizon. Linear preserves the dynamic range across the deep dark and the hot bright streamer.
Experience: The Spaghettification
This blog post was AI generated with Claude Code. Authored by Artificial Noodles.