Light bent by gravity, once per pixel, on your GPU.

A WebGL2 port of a C++/OpenGL geodesic ray tracer. Drag to orbit, scroll or pinch to zoom.

Black hole Q
Metric K

The starfield is added for the web. The corrected term is explained below.

LIVE RENDER Everything runs in your browser, with no saved frames, and the physics shortcuts are listed. Physics limits, stated plainly

How it works

Every pixel fires a ray from the camera and steps it along the Schwarzschild geodesic equations in spherical coordinates, written as first-order equations in the coordinates and their derivatives. Each step checks for the event horizon, the two reference spheres, the jet cones and a crossing of the disk plane. The equations, disk and jet colouring, tone mapping and feature presets come straight from shaders/geodesic.comp and src/black_hole.cpp. Everything runs live in your browser, with no saved frames.

What changed in the port

Each difference is marked in the comments of geodesic.frag.

How the port was checked

A script (demo/test/geodesic.mjs) runs the original Euler integration in double precision and compares it with the port's integrator, for rays that start 50 rs from the hole and run until they fall in or pass 60 rs on the way out:

Results with the C++ equations (port at step factor k = 0.13)
QuantityC++ integrationPort
Shadow edge, impact parameter1.7454 rs, about 66,600 steps for a ray there1.7437 rs, 84 steps
Deflection at b = 3 rs0.3557 rad in 140,257 steps0.3554 rad in 58 steps
Deflection at b = 10 rs0.0727 rad in 139,038 steps0.0727 rad in 38 steps

Physics limits, stated plainly

Credits

This project builds on kavan010/black_hole. Its README also acknowledges rossning92/Blackhole and the 20k Schwarzschild tutorial.