Skip to content

§ Gargantua

A black hole, computed rather than drawn

Most black holes on the web are a radial distortion applied to a background image. This one traces photons backwards from the camera and integrates their null geodesics in the Schwarzschild metric, which is why the far side of the accretion disk appears above and below the shadow.

Raw WebGL2 · no dependencies · renders on scroll

Schwarzschild · r_s = 1 · disk 3–12 r_s

Photon paths integrated as null geodesics

Fig. 1— Schwarzschild black hole with an equatorial accretion disk from 3 to 12 r s, viewed near edge-on. Interactive: drag-free, renders only while on screen.

Metric
Schwarzschild (non-rotating)
Event horizon
r = rs
Photon sphere
r = 1.5 rs
Disk extent
3 – 12 rs (ISCO at 3 rs)
Integration
RK4 in φ, 150–380 steps
Effects
Lensing · Doppler beaming · gravitational redshift
Dependencies
None — raw WebGL2

What is actually being computed

Light does not travel in straight lines near a black hole, and the usual way to fake that on the web is a screen-space distortion — warp the pixels radially and call it lensing. It looks approximately right and is wrong in every detail that matters, because it has no notion of a photon path.

This renders the real thing. For each pixel a photon is traced backwards from the camera and its null geodesic is integrated in the Schwarzschild metric. Written in terms of u = 1/r, in the plane containing the camera and the singularity, the path obeys d²u/dφ² = −u + (3/2)·rs·u². The first term is ordinary orbital motion; the second is the relativistic correction, and it is the entire reason any of the interesting structure exists.

Why the disk appears above and below the hole

The accretion disk is flat and lies in the equatorial plane. Seen from a shallow angle you would expect a line through the middle and nothing else. Instead there is a bright arc over the top of the shadow and another beneath it.

Those are the same disk. Photons leaving the far side of the disk — behind the black hole, travelling away from you — are bent through more than 90 degrees and arrive at your eye anyway. The arc above the shadow is the top surface of the far side; the arc below is its underside, seen through light that passed beneath. You are looking at an object folded over itself by gravity.

There is a second, much thinner ring hugging the shadow: light that orbited the hole one or more times before escaping. The boundary it traces is the photon sphere at r = 1.5·rs, the radius where light can circle indefinitely.

Why one side is brighter

The disk orbits, and at these radii it orbits fast — a substantial fraction of the speed of light. The side rotating toward the viewer has its emission beamed forward and blue-shifted; the receding side is dimmed and reddened. The asymmetry goes as roughly the cube of the Doppler factor, which is why it is so pronounced rather than subtle.

Layered on top is gravitational redshift: photons climbing out of the well lose energy, so the inner disk is dimmed relative to its temperature. Both effects are computed per intersection rather than approximated with a gradient.

Implementation

One fullscreen quad and one fragment shader in raw WebGL2 — no scene graph, no 3D library, no new dependencies. Integration is RK4 in φ with a fixed step, 150 to 380 steps depending on the device tier.

The disk is intersected by tracking the sign of the photon's y-coordinate between steps and interpolating to the crossing point, which correctly picks up multiple crossings when a ray winds around the hole. Stars are procedural and hash-based, so there is no texture to download.

It renders nothing until you scroll to it, pauses when the tab is hidden or the canvas leaves the viewport, drops resolution if frames run consistently slow, and renders a single settled frame under prefers-reduced-motion. Without WebGL2 you get a static frame and the same links.