1Introduction to Black Holes
A black hole is embarrassingly simple to define and infuriatingly hard to draw. The definition: a region of spacetime from which no light signal can escape to the rest of the universe. The difficulty: the reason light can't escape is not that gravity "pulls on photons" like a cannonball slowing in flight — it is that mass has bent the geometry through which light travels, so that every straight line near the hole leads inward. A simulator that merely applies a fake bend to a pretty picture is lying about the mechanism. A simulator that solves the geometry correctly is doing numerical general relativity sixty times a second, per pixel, on a chip designed to draw triangles.
The idea predates Einstein by more than two centuries. In 1783 John Michell and independently in 1796 Pierre-Simon Laplace calculated the radius of a body whose Newtonian escape velocity reaches the speed of light. The modern concept arrived in 1916, months after Einstein published general relativity, when Karl Schwarzschild — serving on the Russian front in WWI — found the first exact solution to Einstein's field equations for a spherical, non-rotating mass. The term "black hole" itself only caught on after 1967, when journalist Ann Ewing popularized it in print (coined in a 1964 lecture by John Wheeler, who later regretted the hype).
1.1 The numbers you will actually render
Everything in a non-rotating simulator scales from one number, the Schwarzschild radius:
$$r_s = \frac{2GM}{c^2} \approx 2.95\ \mathrm{km}\times\frac{M}{M_\odot}$$| Quantity | Value (Schwarzschild) | Why a renderer cares |
|---|---|---|
| Event horizon | $r = r_s$ | Hard black disk of captured rays; also the gravitational time-dilation singularity of the coordinates. |
| Photon sphere | $r = 1.5\,r_s$ | Unstable circular light orbits. Source of the razor-thin photon ring — infinitely many images of the same sky stacked at one radius. |
| Apparent shadow | $r_\text{shadow} = \frac{\sqrt{27}}{2}\,r_s \approx 2.6\,r_s$ | The shadow looks 3.5× wider in area than the horizon. A common amateur error is to draw a black ball of radius $r_s$ — the correct silhouette is bigger. |
| ISCO | $r = 3\,r_s$ | Innermost stable circular orbit. Hot inner edge of any believable thin accretion disk lives here or just outside. |
| Photon capture cone | $b_\text{crit} = \frac{\sqrt{27}}{2}\,r_s$ | Impact parameter threshold. Rays below it spiral in; rays above it escape after bending. |
For scale: the galactic-center black hole, Sgr A*, has $r_s \approx 6$ million km — about 4% of Earth's orbit radius — while the pixel-sharp M87* imaged by the Event Horizon Telescope has an event horizon wider than our solar system. In FlyBlackHole, the companion game built for this paper, we set $r_s = 100$ m so a human-scale spaceship can interact with it; every equation below is unit-free, so the same code renders both.
1.2 What you are actually looking at
A convincing black hole "object" is a stack of visual phenomena, none of which is the hole itself:
- The shadow — an absence of light, 2.6 $r_s$ in apparent radius.
- The photon ring — a sub-pixel-thin bright circle at the shadow edge where light orbited the hole. In real images (and good simulations) it is the sharp inner rim on all sides of the shadow.
- The lensed accretion disk — the far side of the disk appears bent up and over the hole (and a dimmer copy under it), because light from behind the hole reaches the camera by going around it.
- The Einstein-deflected starfield — the whole background sky is a warped mirror; stars crowd and multiply near the shadow.
- Doppler beaming — the side of the disk rotating toward you is several times brighter and bluer than the side rotating away.
Rotating (Kerr) holes, briefly
Real black holes spin, and the Kerr metric adds frame-dragging: the photon region is no longer a sphere, the shadow becomes a D-shape, the ISCO moves inward (to $0.5\,r_s$ for a near-extremal hole), and the disk can extend much closer — making the lensing far more extreme and asymmetric. This paper focuses on Schwarzschild, where one scalar ($r_s$) replaces spin and the physics still produces the iconic look. Chapter 6 notes where Kerr breaks each technique.
2Black Holes on Screen: A Depiction History
2.1 The vortex era (1960s–1990s)
Before computer graphics, black holes were drawn — and drawn wrong, because no one had ever seen one. Star Trek: The Motion Picture (1979) sends the Enterprise through a "black hole" that looks like a swirling paint mixer: bright, central, and full of things. The famous 1979 Encyclopedia Britannica illustration — a glowing donut seen at an angle with a bright center — was rendered by artist Brill with advice from NASA's Goddard center, and got the orientation of the lensing roughly right but the center wrong: a real black hole's center is the blackest thing in frame. For two decades, movies copied that illustration as fact. Event Horizon (1997) featured a hole that opens into literal hell; physically, the only thing past the horizon is more physics.
2.2 Contact (1997): the first informed rendering
Carl Sagan's novel described a traversable wormhole, and for the film the team at Digital Domain — with theoretical backing from Kip Thorne — built a ray-traced wormhole with a physically-derived lensing map: a ring of warped starlight, the external galaxy smeared into an arc. It was the first screen black-hole-adjacent object whose light paths came from equations rather than concept art. Notably, the artists found the real thing was less visually dramatic than invented vortexes, and Sagan himself asked them to add a "sparkly" rim so audiences would read it as special effects. The tug-of-war between physics and spectacle was born here.
2.3 Interstellar (2014): the special mention
No depiction deserves more attention than Interstellar's Gargantua, and it is a special case in every sense:
- Physics-first production. Director Christopher Nolan hired Kip Thorne as executive producer with an unusual contract: no law of physics would be broken in the film. Thorne's collaborator on the visuals was theoretical physicist James Doyle, who had written a 1984 Caltech senior thesis on exactly this problem — what black holes look like to a camera.
- A custom renderer. Double Negative (D&N) built an independent renderer (pictl) alongside their main pipeline, running a GR ray tracer: for each pixel, integrate the null geodesic backward through Schwarzschild spacetime until it hits the disk or escapes to a starfield. Roughly 800 hours of CPU time per frame for the IMAX shots — 30 million CPU-hours across the show by some accounts. The render used a semi-analytic shortcut: rather than stepping blindly, they solved for where the geodesic crosses the equatorial plane (where the thin disk lives), then marched between crossings. That trick is still the best idea in real-time black hole rendering (Chapter 6).
- The Doppler decision. Physically, a ~6% spin Gargantua with a ~10,000 K disk should show strong Doppler beaming: one side of the disk several times brighter and shifted red on the other side. That image (produced by D&N) looked, in Nolan's words, too much "like a special effect" — asymmetric and gaudy. The released film shows a near-symmetric, gently graded disk: correct geodesics, deliberately muted relativistic color. Compare Figure 3 (physics on) with Figure 4 (film look). The paper co-written by D&N's Oliver and Paul Weir was published openly on arXiv — the first time a blockbuster's black-hole renderer came with a peer-reviewed appendix.
- What they got famously right: the shadow is larger than the horizon; the far side of the disk appears above and below the shadow simultaneously (the "halo over the top" that audiences assumed was a mistake); the thin photon ring at the shadow's rim; lensing magnifies rather than "sucks" the image inward.
- What they bent: the muted Doppler asymmetry, and a slightly soft photon ring (real rings at achievable resolution are sub-pixel; blurring them sold the effect better than aliasing).
2.4 Reality overtakes the movies (2019–present)
On April 10, 2019 the Event Horizon Telescope released the first direct image of a black hole — M87*, an orange smear with a dark center, essentially the Interstellar look at 20-pixel resolution, which is exactly what an interferometer with limited uv-coverage should produce. Sagittarius A* followed in 2022. Cinema's loop closed: audiences now recognize a black hole because it looks like a movie black hole, and the movies turned out to be roughly right. Meanwhile real-time GPU engines (and FlyBlackHole, Chapter 7) brought GR ray tracing to consumer graphics cards at 60 fps — computation that cost Interstellar hundreds of CPU-hours per frame.
3The Math: Light in Curved Spacetime
3.1 The Schwarzschild metric
General relativity says matter tells spacetime how to curve; spacetime tells light how to travel. For a spherical, uncharged, non-rotating mass, the line element is
$$ds^2 = -\left(1-\frac{r_s}{r}\right)c^2 dt^2 + \left(1-\frac{r_s}{r}\right)^{-1} dr^2 + r^2\left(d\theta^2 + \sin^2\theta\, d\phi^2\right)$$Light follows null geodesics: paths where $ds^2 = 0$. A planetarium-scale simulator would integrate the full geodesic equation with Christoffel symbols, but for Schwarzschild three facts collapse the problem into something a GPU can digest: spherical symmetry (motion stays in a plane), conservation of energy $E$, and conservation of angular momentum $L$.
3.2 The orbit equation and the effective potential
Writing $u = 1/r$ and differentiating with respect to the azimuthal angle $\phi$, the radial motion of any light ray reduces to a single beautiful equation:
$$\frac{d^2u}{d\phi^2} + u = \frac{3}{2}\,r_s\,u^2$$This equation exposes the physics at a glance. The right-hand side — the GR correction — vanishes at large distance (straight lines recovered; the classic $1919$ eclipse deflection $\hat\alpha = 2r_s/b$ falls out of a first-order perturbation) and dominates near the hole. Solving for circular photon orbits ($u'' = 0$) gives $u = 2/(3r_s)$, i.e. the photon sphere at $r = 1.5\,r_s$ — and the fact that it is unstable (a nudge inward sends the photon spiraling in; a nudge outward sends it away) is why near-critical rays pile up into the photon ring.
3.3 Why the shadow is 2.6 $r_s$ wide
The separatrix between capture and escape is found exactly. For a photon, the radial equation admits an effective potential with a peak at $r = 1.5\,r_s$ at height $(L/E)^2 = 27\,r_s^2/4$. A ray from far away with impact parameter $b = L/E$ is captured iff it can reach the peak:
$$b \;<\; b_\text{crit} = \frac{\sqrt{27}}{2}\,r_s \approx 2.598\,r_s$$Since the apparent angle of a distant ray on the camera equals its impact parameter over distance, the silhouette on the sky is a disk of radius $\sqrt{27}/2\,r_s$ — 30% larger in radius than the horizon, 3.5× in area. A second way to see it, useful for rendering: stand anywhere, in vacuum, at any radius, and the black hole blocks a cone of directions of half-angle $\psi$ given by $\sin\psi = b_\text{crit}\sqrt{1-r_s/r}\;/\;r$. At the horizon, $\sin\psi = \frac{\sqrt{27}}{2}\cdot 0 \to$ the shadow covers… more than half the sky and grows as you fall, filling the entire sky at the singularity. Keep this formula — it is a free, exact "black disk mask" that costs one square root and pairs well with approximate lensing.
3.4 Time dilation and redshift
Clocks deeper in the potential tick slower by $d\tau/dt = \sqrt{1-r_s/r}$, and light climbing out is redshifted by $1+z = 1/\sqrt{1-r_s/r}$. For the simulator this means the inner disk's thermal spectrum visibly reddens and dims as it approaches the horizon — the inner edge doesn't end abruptly, it fades toward infrared. At $r = 1.01\,r_s$ the redshift factor is 10×: the disk's visible light arrives as microwaves. In practice you multiply the emitted radiance by $g^4$ (photon rate $g$ × energy $g$ × two arrival-rate factors, from Liouville's theorem) — see Figure 8's redshift discussion.
Free-fall time, for the HUD
A body dropped from rest at infinity reaches the singularity from the horizon in proper time $\tau = \tfrac{4}{3}\,r_s/c$ — 3.3 microseconds for a 10 $M_\odot$ hole, but ~7 hours across Sgr A*'s horizon radius… and for the 100 m $r_s$ in FlyBlackHole, about 0.4 milliseconds of ship-board time. Game physics licenses generous fudge factors here; the twin HUD clocks (ship vs. far universe, differing by $1/(1-r_s/r)$) are honest.
4The Accretion Disk: Making It Glow
4.1 Geometry and temperature
The black hole is invisible; everything you love is the disk. A thin accretion disk is modeled as Keplerian circular orbits between roughly $r_\text{in} \approx 3\,r_s$ (ISCO) and $r_\text{out} \sim 10\text{–}15\,r_s$ (a soft outer falloff). The canonical Novikov–Thorne temperature profile is well approximated by a power law:
$$T(r) = T_\text{in}\left(\frac{r}{r_\text{in}}\right)^{-3/4},\qquad T_\text{in} \approx (10^5\text{–}10^7\,\mathrm{K})\left(\frac{M}{M_\odot}\right)^{-1/4}$$Stellar-mass disks peak in X-rays — invisible to your eyes and to your framebuffer. Cinematic and game disks (including FlyBlackHole's 12,000 K inner edge) cheat mass upward or temperature downward so the blackbody peaks in visible orange-white. A simple, gorgeous approximation: evaluate a blackbody or a hand-tuned color-ramp at $T(r)$, multiply by $T^4$ (Stefan–Boltzmann) for intensity, and you have a physically-shaped glow in ten lines of shader.
4.2 Doppler beaming — the asymmetric signature
Disk material at $r$ moves at $\beta = \sqrt{r_s/2r}$ (Keplerian, at $r = 3\,r_s$ that is half the speed of light). A moving blackbody is brighter toward its motion by the relativistic Doppler factor $\delta = 1/[\gamma(1-\boldsymbol\beta\cdot\hat n)]$, with observed intensity $\propto \delta^{3\text{–}4}$ and observed temperature $T_\text{obs} = \delta\,T_\text{emit}$.
The full per-pixel radiance model that a serious render evaluates along each ray is then: sample the ray's crossings of the disk plane; at each crossing evaluate $T(r)$, project the orbital velocity onto the ray direction, combine the Doppler factor $\delta$ with the gravitational redshift factor $\sqrt{1-r_s/r}$ into a net shift $g$, and accumulate $g^4\,B_\nu(g\,\nu)\,d\ell$ with the disk's emissivity. Two crossings per ray is usually plenty (direct far side + one lensed image); four covers rays that loop the photon sphere.
4.3 Turbulence and the noise problem
Real disks are magnetized plasma with magnetorotational turbulence — spotty, variable. Simulators fake this with domain-warped fBM noise advected at the Keplerian rate (so the pattern shears, as it physically must: inner rings lap outer rings, producing the characteristic spiral smearing). Advection phase must be continuous across frames or the disk boils; use $\phi_\text{noise} = \phi - \Omega(r)\,t$ in the noise argument rather than any per-frame seed.
5Why a Graphics Card Fights You
It is worth being blunt about the mismatch: GPUs are astonishing parallel machines built around an assumption that gravitational lensing violates in every fiber. The assumption is straight lines and fixed geometry.
5.1 Rasterization is the wrong model of light
The graphics pipeline (whether fixed-function of 1998 or the mesh-shader pipeline of today) works forward from geometry: vertices → triangles → fragments → framebuffer. That is the inverse of what a black hole scene needs. The scene has essentially no surfaces; it has a light-field distortion. The correct dataflow is backwards ray tracing — for each pixel, trace where its light came from — and even then, "where it came from" requires numerically integrating an ODE, not intersecting a primitive. Rasterizers can draw a black hole; they cannot be one.
5.2 The five concrete enemies
| Enemy | What it costs you | Standard mitigation |
|---|---|---|
| 1Variable step count | Rays near the photon sphere need 5–20× more steps than distant rays. SIMT hardware runs warps in lockstep: one divergent near-critical pixel drags 31 neighbors to its step count. This — not raw FLOPS — is why naïve per-pixel geodesic renderers stutter at the shadow edge. | Two-pass rendering (cheap pass + high-precision pass only in a screen-space annulus around the shadow); adaptive $h$ with a hard step cap; importance-based step limits. |
| 232-bit float precision | RK4 over $r\in[1,20]r_s$ with float32 accumulates visible jitter at the pixel level — a "shimmering shadow edge" that reads as a bug. Near-critical rays are chaotic: float32 changes which sub-ring a ray lands in. | Unit-scale the scene to $r_s = 1$; use the integrated-potential form (below) rather than double summation; double-float (float2 hi/lo) tricks for the position accumulator; temporal filtering to hide residual noise. |
| 3No frame-to-frame coherence | A rolling camera changes every pixel's geodesic. Unlike ray tracing (where denoising reuses neighbors), lensing fields change fast near the hole. | Reproject previous frame's radiance along its own geodesic ("GR reprojection") as a temporal prior; jittered sub-pixel sampling + TAA. |
| 4The photon ring is sub-pixel | Physically the ring is infinitely thin in the limit. At 1080p your integration precision, not the physics, determines its brightness — undersampled rings flicker; over-smoothed rings look fake. | Render the ring analytically as a separate 2–4 px glow pass using the capture-cone angle (Section 3.3), let the integrator handle the rest. |
| 5Bandwidth vs. LDR pipelines | Doppler factors give real luminance ranges of 10–100:1 across a single disk; 8-bit channels clip either the bright limb or the dark horizon. | HDR render targets (RGBA16F minimum), filmic tonemap as a late full-screen pass so physics never sees the tonemap. |
5.3 What the card is good at
After the complaint, the surprise: a midrange GPU has exactly the right shape for this problem. A null geodesic is embarrassingly parallel across pixels — no two rays talk to each other — which is the one workload SIMT loves. Modern cards add tensor cores, mesh shaders, and — most relevantly — compute shaders, which decouple the pipeline from triangles entirely: a compute pass writing to an HDR texture is a ray tracer's clean slate. Hardware ray-tracing cores (BVH traversal) do not help directly: they accelerate intersections with static primitives, and a geodesic integrator's inner loop is arithmetic, not tree traversal — though the disk plane can be treated as a primitive once you know where the bent ray will cross it.
The arithmetic budget: one RK4 step of the geodesic equation is ~20 FLOPs. A 1080p frame (2M pixels) × 100 average steps × 20 FLOPs ≈ 4 GFLOP per frame — 240 GFLOP/s at 60 fps. A GTX 1650 has ~3 TFLOPS. The physics fits on a laptop GPU with 1% headroom if you write it well. The challenge is never the raw integration; it is enemies 1–5 above.
6Techniques: A Ladder from Fakes to Geodesics
6.1 Tier 0 — Texture and screen-space fakes
A billboarded "black hole" PNG with a screen-space radial-distortion post shader (UV offsets pulling outward from screen center). Cost: <0.1 ms. Used extensively in games for wormholes and portals. It fails the honest-test instantly: the distortion is radially symmetric in screen space, so it breaks the moment the camera translates — the effect is glued to the viewport, not the world. Fine for a cutscene; a lie for a flight sim.
6.2 Tier 1 — The deflection-map / lookup-table trick
Because Schwarzschild lensing is static and spherically symmetric, the mapping from "observed direction" to "true sky direction" is a 2D function of only two numbers. Precompute it once (the reference treatment is Bruneton & Bertails-Descoubes's Real-time High-quality Black Hole Shader and its BTFRK tables), store as textures, and at render time each pixel becomes one table lookup plus one environment tap. Cost: ~0.2 ms at 4K. Fidelity: essentially exact for a static camera around a non-rotating hole — but a moving camera needs the 3D generalization (tables indexed by radius and view angle), and Kerr breaks the separability that made tables legal. This is the technique to recommend to a game team that wants "lensing, but it must not touch frame budget."
6.3 Tier 2 — Pseudo-geodesic ray marching (potential fields)
Trace rays as polylines that bend each step by an analytic gradient of a post-Newtonian potential: $\Delta\hat{d} \propto -\nabla\Phi_\text{eff}\,ds$. Cheap (10–30 steps), coherent, and tunable — but wrong in the strong field: it won't reproduce the $\sqrt{27}/2$ shadow, and multi-winding photon-ring rays don't emerge. Good for lensing of background galaxies at cosmological distances; not for the hole itself.
6.4 Tier 3 — Per-pixel geodesic integration (the real thing)
The core algorithm. For each pixel, launch a ray from the camera with direction $\hat d$ and integrate backwards along the null geodesic until termination (escape to sky, or capture radius). The form used in FlyBlackHole and many research demos avoids Christoffel symbols entirely by using the conserved quantities and writing acceleration in Cartesian form:
$$\frac{d^2\mathbf{x}}{d\lambda^2} = -\frac{3}{2}\,\frac{r_s\,h^2}{r^5}\,\mathbf{x},\qquad h = |\mathbf{x}\times\mathbf{v}|$$Then: adaptive-step RK4 (halve $h$ when $r$ drops below a few $r_s$, since curvature scales as $r^{-5}$ — see Figure 10); at each step test for a crossing of the disk plane ($z$ sign change) and evaluate the disk radiance model of Chapter 4 at interpolated crossings; terminate when $r < r_s$ (capture: add nothing) or when $r > r_\text{far}$ with outward velocity (escape: sample the starfield cubemap).
6.5 Tier 4 — Path-traced GR (film territory)
Multiple scattering, full radiative transfer through the disk medium, ion spectra, time-dependent emission — what academic groups render for comparison images with the EHT, and roughly what Interstellar's pictl renderer approximated. Minutes-to-hours per frame on a workstation. Include it here for honesty about the ceiling; nothing about it fits 60 fps except its data structures.
6.6 Where Kerr breaks the ladder
- Tables: the separable Carter constant saves you — lensing tables still exist for Kerr (equatorial-camera tables are standard) — but off-equatorial cameras need bigger tables or interpolation across spin.
- Cartesian form (6.4): the simple $-x/r^5$ force gains frame-dragging terms (a velocity-dependent component $\propto a$); still ~25 lines in a shader, but $h$ is no longer the only conserved quantity.
- Shadow: D-shaped and spin-rotated; the capture-cone analytic mask needs Bardeen–Press solutions.
- Disk: ISCO moves with spin; counter-rotating disk truncates far out, co-rotating runs hot and close — the visual difference is enormous and is how real astrophysicists "see" spin.
7Case Study: FlyBlackHole
The companion project to this paper, FlyBlackHole, is a first-person spaceship flight into a Schwarzschild black hole, built natively for Linux on Godot 4.7 / Vulkan. Every visual claim in this paper was verified against its renders.
| Design decision | Choice | Rationale |
|---|---|---|
| Integration | Adaptive-step RK4 per pixel, Cartesian form (6.4) | Accuracy headroom for multi-winding rays; adaptivity tames the warp-divergence cost (enemy 1) near the shadow edge. |
| Units | $r_s = 100$ m, ship-scale camera | Human flight scale; all equations unit-free. Float32 safe because the scene is unit-scaled in $r_s$ (enemy 2). |
| Disk | 3.2–14 $r_s$, Keplerian $\Omega\propto r^{-3/2}$, blackbody ramp, Doppler + gravitational shift, fBM turbulence advected at $\Omega(r)$ | Chapter 4, at real-time cost. |
| Starfield | HDR cubemap sampled at the ray's asymptotic direction after escape | Lensing of the sky is free — the sky is sampled wherever physics says the ray pointed. |
| Horizon logic | $R$-reset disabled inside $r_s$; twin HUD clocks (ship proper time vs. far-universe time at $1/(1-r_s/r)$) | The one-way door is the point of the experience; the clocks are the physics lesson. |
| Inside the horizon | External universe rendered through the capture cone as a shrinking bright window | Physically correct view of the outside for an infalling observer: everything beyond the cone is causally dark. |
7.1 Measured behavior
On the development GPU (a midrange 4 TFLOP-class card) the geodesic pass runs at 60 fps at 1080p with adaptive stepping; frame cost is dominated not by steps but by divergence near the shadow annulus, matching Chapter 5's prediction — disabling lensing drops the pass to a plain cubemap blit (<0.05 ms), a ~20× swing. The most surprising casualty in early builds was float32 precision on the camera's world position at $r \gg r_s$ (coordinate magnitudes in the $10^4 r_s$ star field): the fix was rendering in camera-local geodesic coordinates with the hole's position as the only large value — worth writing on the wall of any engine integration: never integrate a geodesic in world coordinates.
8A Recipe You Can Build This Weekend
Everything you need for a physically honest, 60 fps black hole in any compute-capable renderer (Godot, Unity compute, Unreal compute, raw Vulkan/Metal/WebGPU):
// Per-pixel GR lensing — the whole algorithm (GLSL-ish, camera-local coords, rs = 1) vec3 renderRay(vec3 dir) { vec3 x = vec3(0.0); vec3 v = dir; // start at camera vec3 h = cross(x - holePos, v); float h2 = dot(h, h); vec3 acc = vec3(0.0); // accumulated disk radiance vec3 prev = x; float dt = 0.02; for (int i = 0; i < 300; i++) { x = integrateRK4(x, v, dt); // d²x/dλ² = -1.5 * h2 * (x-p) / r⁵ float r = length(x - holePos); if (r < 1.0) return acc; // captured: black if (r > 60.0 && dot(v, x-holePos) > 0.0) return acc + sky(normalize(v)); // escaped: starfield if (prev.y * (x - holePos).y < 0.0) // disk-plane crossing acc += sampleDisk(prev, x); // T(r)·T⁴ ramp, δ³·⁵ beaming, // sqrt(1-1/r) redshift, noise dt = clamp(0.05 * r * r, 0.002, 0.5); // adaptive: fine near hole prev = x; } return acc; }
Pitfalls checklist (each of these cost a real project a day)
- Integrating in world coordinates → float jitter at distance. Use camera-local.
- Testing disk crossings per-step without interpolation → banded, aliased disk edge. Interpolate the crossing point.
- Forgetting the ray can cross the disk plane 4 times (direct, lensed over, lensed under, double-loop) → missing images. Loop the crossing test, don't early-exit at first hit.
- Tonemapping before beaming → the asymmetric limb is baked away. Keep HDR until the last pass.
- Fixed step size → either 4× wasted cost on distant pixels or a molten, noisy shadow edge. Adaptive $dt \propto r^2$.
- Per-frame noise seeds → disk boils. Phase-lock noise to orbital angle $\phi - \Omega(r)\,t$.
8.1 Suggested parameter set (validated)
| Parameter | Value | Parameter | Value |
|---|---|---|---|
| $r_s$ | 1.0 (unit-scaled) | Disk inner / outer | 3.2 / 14 $r_s$ |
| Escape radius | 40–60 $r_s$ | Inner-edge temperature | ~12,000 K (visual) |
| Max integration steps | 250–350 | Adaptive $dt$ | $0.05\,r^2$, clamped |
| Render target | RGBA16F | Camera FOV | 60–75° (wider exaggerates lensing) |
Further reading path: Doyle's 1984 thesis for the visual physics; the Weir & Oliver Interstellar paper on arXiv for a production implementation; Hsu et al.'s and Ringer's papers for lookup-table real-time methods; and any graduate text for the Kerr extension. Then open a compute shader and go make the shadow.
9References
- Darwin, C. G. (1959). "The gravitational deflection of light." Proc. Roy. Soc. A 254:393. — exact photon orbits and the capture cone.
- Bardeen, J. M. (1973). "Timelike and null geodesics in the Kerr metric." In Black Holes, Les Houches.
- Doyle, L. R. (1984). What is the gravitational lensing signature of a black hole? Senior thesis, CalTech. — the visual-physics ancestor of Interstellar.
- Weir, P., James, O., et al. (2015). "Designing Interstellar's black hole." arXiv:1502.03808; Class. Quantum Grav. 32. — production GR renderer.
- Himwich, T. et al. / EHT Collaboration (2019). "First M87 Event Horizon Telescope Results." ApJL 875:L1. — and Sgr A* results, 2022.
- Ressler, S. M. & Lamm, H. G. (2004). "Perspective views of relativistic radiation from a thin accretion disk." A&A 425:223. — disk rendering reference.
- Bruneton, E. & Bertails-Descoubes, F. (2023). "A Real-time High-quality Black Hole Shader." ebruneton.github.io/black_hole_shader — beam tracing with precomputed tables (the BTFRK method); live demo.
- Matthews, T. (2026). FlyBlackHole: native Linux/Vulkan GR flight simulator. Local repository:
~/FlyBlackHole. - Matthews, T. (2026). How Gravity Can Be a Result of Time Dilation — companion paper on the metric foundations.