Gargantua — a real-time Kerr black hole ray-tracer (React Three Fiber)

Built a real-time black hole renderer on top of R3F — every photon path is
integrated through an actual Kerr geodesic solver rather than faked with a
lensing sprite, and the accretion disk’s brightness/color come from the same
equations that describe a real spinning black hole

Github

Live

What’s actually simulated, not just styled:

  • Photons integrate through the Kerr–Schild form of the Kerr metric
    (Cartesian, horizon-penetrating coordinates), evolved with a symplectic
    Euler step on the Hamiltonian H = ½(−E² + |p|² − fΦ²) — frame dragging
    falls out of the integration itself.
  • The disk starts at the exact prograde ISCO (Bardeen–Press–Teukolsky
    formula) for spin a★ = 0.95, and follows a Novikov–Thorne temperature
    profile, so it cools to black right at the inner edge instead of glowing
    up to the horizon.
  • Color comes from a Planckian blackbody fit at the gravitationally +
    Doppler-shifted temperature; brightness from δ⁴ relativistic beaming
    (Liouville’s theorem) — that’s why the approaching limb outshines the
    far side.
  • The background sky is a real three.js scene (nebula dome + a 3D star
    point-cloud + a background galaxy), rendered once to an HDR cubemap via
    CubeCamera. The geodesic integrator samples it with the bent ray
    direction, so the nebula/stars get lensed into the halo exactly like the
    disk’s far side does.
  • The HUD’s time dilation, local gravity, and tidal-force readouts are
    computed live from the camera’s exact Boyer–Lindquist position each
    frame, scaled to a real ~1e8 solar-mass hole.

Post-processing is a standard HDR pipeline: mipmap Bloom → ACES filmic
tonemap → grain/vignette.

Stack: Next.js · React Three Fiber · drei · @react-three/postprocessing

Would love feedback, especially from anyone who’s done geodesic ray-marching
in GLSL before — curious if there’s a cleaner way to handle the disk’s
razor-thin-slab sampling without the adaptive step clamping I ended up with.

3 Likes

Very cool!

It looks like part of it is textured with a non-tilable texture? That’s probably an easy fix in photoshop…

Regarding the breakdown at grazing angles.. that’s above my paygrade. :smiley: but very cool nonetheless.

1 Like

There’s actually no texture to fix — it’s all procedural fBm noise. That seam is real though: the nebula’s sampled in (atan2(z,x), asin(y)), and atan2 wraps at ±π so the edges don’t match. It’s a shader fix (3D noise), not Photoshop.

The grazing angles are a known issue: rays skim nearly parallel to a razor-thin disk, so the raymarch step overshoots it and bands. Adaptive stepping near the disk would fix it — just haven’t gotten to it yet.

1 Like

NewBi Brother !!!

Ahh makes sense.