Three.js Scroll Black Hole — Accretion Disk Dive

Three.js Scroll Black Hole Approach · Scroll · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

5,200-particle accretion disk on Keplerian ω ∝ r^−1.5 orbits — the inner edge genuinely laps the rim
Blackbody-style temperature gradient via per-particle vertex colors, white-hot core to rust rim
Additive blending stacks crowded inner particles into a glowing band with no texture
The event-horizon shadow is a pure black MeshBasicMaterial sphere — unlit by definition
Photon ring torus that pulses on clock time and brightens/swells with approach
Time-dilation metaphor: disk clock multiplied up to 12× by p^2.4, reported live in the HUD
FOV creep 60°→84° with per-frame projection updates for the pulled-in horizon stretch
Stateless particle math — scrub-exact at any speed, decelerating smoothly in reverse

About this UI Snippet

How to Build a Scroll-Driven Black Hole Approach With Three.js and GSAP

Screenshot of the Three.js Scroll Black Hole Approach snippet rendered live

The Three.js Scroll Black Hole Approach snippet drops the camera toward a black hole wrapped in a 5,200-particle accretion disk — inner particles white-hot and orbiting fast, outer ones rust-red and slow, a photon ring hugging the shadow — while scroll accelerates the fall, multiplies the disk's apparent speed as a time-dilation metaphor, and creeps the camera's field of view wider for that stretched, pulled-in horizon feeling. Where the planet approach brakes into orbit, this one accelerates past the point of no return.

Keplerian orbits from a power law

Each disk particle stores polar parameters — radius, phase, vertical tilt, and an angular velocity ω = 14 / r^1.5 — the same r^−3/2 falloff as real Keplerian orbits, so the inner disk visibly laps the outer disk exactly the way accretion physics demands. Positions are computed fresh every frame from parameters plus time (the stateless design shared with the tornado vortex), which keeps the scrub exact at any scroll speed. Radius distribution uses pow(rand, 1.6) to crowd particles toward the inner edge where the action is.

Temperature as vertex color

Real accretion disks are hottest where orbital energy dissipates fastest — the inner edge. Each particle's color is assigned once at build time by double-lerping white-hot → orange → rust across normalized radius, stored in a color BufferAttribute with vertexColors: true and AdditiveBlending. Where particles crowd near the inner edge, additive blending stacks their brightness into a glowing band — the blackbody gradient emerges from geometry density rather than any texture.

The shadow is just an unlit sphere

The black hole itself is the cheapest mesh in the scene: a MeshBasicMaterial sphere in pure black, which ignores lighting by definition. Against the additive disk and starfield, an object that reflects *nothing* reads as a hole in space — no shader needed. The photon ring is a thin warm torus riding just outside the shadow, pulsing subtly on clock time and brightening plus swelling with approach, standing in for the lensed light band made famous by the EHT image and *Interstellar*.

Time dilation as a speed multiplier

The scroll's signature move: disk time advances as t × (1 + p^2.4 × 11), so at full approach the disk spins eleven times faster than at the start, and the HUD reports the multiplier as TIME DILATION n×. It is a metaphor rather than relativity — a real infalling observer would see the opposite — but it compresses "the universe speeds up as you fall" into one legible, scrubbable number. Because the multiplier applies to *clock* time inside the stateless position math, scrolling back down smoothly decelerates the disk with zero state to unwind.

FOV creep and lensing hints

Nearing the horizon, camera.fov interpolates from 60° to 84° with updateProjectionMatrix() each frame — a dolly-zoom-like stretch that makes the shadow balloon in the final stretch of scroll. The starfield counter-rotates slightly against the camera swing as a cheap suggestion of gravitational lensing, and the disk tilts more edge-on as the camera dives toward the orbital plane, trading the top-down spiral view for the *Interstellar* silhouette. For the gentler cousins of this scene, see the galaxy formation and starfield warp snippets.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You do not need to research accretion physics to extend this scene. Paste this snippet's HTML, CSS, and JS into an AI assistant like Claude and ask it to explain the Keplerian ω ∝ r^−1.5 law in the code, why additive blending creates the hot inner band, or what the FOV creep contributes. The same assistant can push the realism or the drama — a Doppler-beaming brightness asymmetry (approaching side brighter, one line of dot-product math), infalling particle streams that spiral from the disk's inner edge into the shadow, a redshift color ramp applied by approach progress, or the whole disk converted to a ShaderMaterial for 50,000 particles. It can also retune the dilation curve so the spin-up peaks exactly where your page's key copy lands. Treat the code as a starting point to interrogate and reshape, not a finished artifact.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "scroll-driven black hole approach" in plain HTML, CSS, and JavaScript using Three.js and GSAP's ScrollTrigger plugin, all loaded from a CDN (no bundler, no build step).

Requirements:
- A pinned full-viewport section with a canvas, WebGLRenderer, PerspectiveCamera (initial FOV 60, resized with aspect on window resize), near-black background, and NO lights — every material must be self-lit.
- The event horizon: a SphereGeometry with pure black MeshBasicMaterial, plus a thin warm TorusGeometry photon ring just outside it that pulses scale on clock time and brightens/swells with approach progress.
- An accretion disk of ~5,000 particles in one THREE.Points: each particle stores ONLY radius (7.4–29, crowded inward via pow(rand, 1.6)), phase, small vertical tilt, and Keplerian angular velocity ω = 14 / r^1.5, all from a seeded sin-hash. Per-particle vertex colors double-lerp white-hot → orange → rust by normalized radius; material uses vertexColors, AdditiveBlending, depthWrite false. Tilt the disk ~0.42 rad.
- ~1,500 background stars on a spherical shell.
- One GSAP tween (ease "none") scrubbing p 0→1 on a ScrollTrigger with pin: true, scrub ~0.6, end ~+=500%.
- Each frame: distance = 90 − 76 × p^1.7 (accelerating fall); disk time T = clock × (1 + p^2.4 × 11) × 0.22 — a time-dilation multiplier reported in a HUD as "TIME DILATION n.nn×"; recompute every particle position from (radius, phase + T × ω); tilt the disk ~0.5 rad more edge-on with p; creep camera.fov from 60 to 84 calling updateProjectionMatrix(); counter-rotate the starfield slightly against the camera swing as a lensing hint.
- Camera orbits slowly (clock) plus a p-linked 1.6 rad swing, descending toward the disk plane, lookAt origin; intro overlay fades at p > 0.02.
- Confirm reverse scrolling backs the camera out while the disk decelerates smoothly — all particle math must be stateless.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Load the three CDN scriptsAdd three.min.js, gsap.min.js, and ScrollTrigger.min.js in that order before the snippet JS.
  2. 2
    Paste HTML, CSS, and JSA distant black shadow ringed by a glowing accretion disk hangs among stars; the HUD reads TIME DILATION 1.00×.
  3. 3
    Scroll to fallDistance collapses on an accelerating curve while the disk visibly spins up — the inner edge lapping the rim faster and faster.
  4. 4
    Watch the horizon growFOV creeps from 60° to 84°, the photon ring brightens and swells, and the disk tilts toward its edge-on silhouette.
  5. 5
    Scroll back outThe fall reverses and the disk decelerates smoothly — positions are stateless functions of parameters, clock, and the scrubbed value.
  6. 6
    Tune the physicsChange the ω = 14 / r^1.5 falloff for stiffer or softer differential rotation, or the p^2.4 dilation curve for a gentler spin-up.

Real-world uses

Common Use Cases

Space, science, and astronomy sites
An EHT-style shadow with a physically ordered disk gives observatories and science media a hero that survives expert scrutiny.
Sci-fi game and film promos
The Interstellar silhouette at full approach is a ready-made key art moment; pair with a starfield warp above it.
"Gravity" brand metaphors
Products that pull everything in — aggregators, data lakes, marketplaces — get the metaphor rendered literally, disk and all.
Teaching differential rotation
The ω ∝ r^−1.5 law is visible: students watch inner orbits lap outer ones, and the scrub lets them pause and verify.
Dark-theme portfolio centerpieces
A restrained, physical alternative to neon effects like the lightning orb — all warmth against pure black.
Music and event visuals
Bind the dilation multiplier to audio tempo instead of scroll for a disk that spins with the drop, cousin to the audio waveform visualizer.

Got questions?

Frequently Asked Questions

Each particle stores an angular velocity ω = 14 / r^1.5 — the Keplerian power law, where orbital speed falls with the 3/2 power of radius. Inner particles at r ≈ 7.4 sweep many times faster than rim particles at r ≈ 29, so the disk visibly shears rather than rotating as a plate. Positions are recomputed each frame from radius, phase, and shared disk time, never integrated.

MeshBasicMaterial ignores every light in the scene, so the sphere renders as an absolute-black disc from any angle — visually indistinguishable from "no light escapes." Surrounded by additive-blended disk particles and stars, the eye reads the void as depth. A shader could add lensed background distortion, but the flat shadow plus photon ring already matches the iconic EHT silhouette.

Disk time is t × (1 + p^2.4 × 11): at zero scroll the disk runs at 1×, at full approach nearly 12×. Because the multiplier scales the clock inside stateless position math, the spin-up is smooth in both directions and the HUD just prints the same factor. Physically it is a storytelling inversion (an infalling observer sees the outside universe speed up, not the disk), chosen because it makes the approach feel legible.

Interpolating fov from 60° to 84° (with updateProjectionMatrix() each frame) stretches peripheral space as the camera closes in — the dolly-zoom vocabulary for "space itself is distorting." Combined with the accelerating distance curve (90 − 76 × p^1.7), the shadow balloons in the last quarter of scroll far faster than linear motion would suggest, which is exactly how falling into a gravity well should feel.

Yes. Export via the JSX, Vue, Angular, or Tailwind buttons. Build the particle arrays and ScrollTrigger inside a mount effect against a canvas ref, keeping the Float32Arrays and parts array in effect scope. On cleanup kill the ScrollTrigger, dispose the disk, star, hole, and ring geometries/materials, call renderer.dispose(), and reset camera.fov if the camera object is shared.