Black Hole Simulator — real-time ray marching in GLSL
Black Hole Simulator renders a black hole in real time on the GPU using ray marching in a GLSL fragment shader, with no precomputed imagery and no offline render step. It offers five visualisation modes, including Interstellar-style gravitational lensing and a Doppler-shift heatmap.
What ray marching does here
Ray marching renders an image by walking a ray forwards from the camera in small discrete steps and asking, at each step, whether the ray has hit something. Unlike rasterisation, which projects geometry onto the screen, this approach builds the image from a distance function evaluated per pixel, so shapes can be described mathematically instead of as triangle meshes.
That property is what makes it a good fit for a black hole: there is no surface to model. The interesting visual features come from how light paths bend near the mass, and those paths can be integrated numerically per pixel rather than approximated with geometry.
The trade-off is cost. Every pixel performs many iterations, so the fragment shader is the bottleneck and resolution is the primary quality dial. The renderer runs interactively at reduced resolution and depends on the GPU rather than the CPU for all per-pixel work.
The five modes
The lensing in every mode is an artistic approximation built from a distortion field. It is not a solution of the geodesic equations for a Schwarzschild or Kerr metric. That distinction matters if you arrived here looking for a physically accurate simulation: this is a graphics project, and the repository says so as well.
- Cinematic — warm accretion colouring with strong lensing, in the visual style popularised by Interstellar
- Doppler heatmap — colours the disc by relative approach velocity, so the side rotating towards the viewer reads differently from the receding side
- EHT-style approximation — a visual approximation of the ring appearance seen in Event Horizon Telescope imagery
- Additional modes covering alternative colour mappings and camera treatments
- Interactive camera control across all modes, so the viewing angle can be changed while the render continues
Why an approximation is still worth building
A physically accurate renderer integrates null geodesics through a curved spacetime metric, which is both more code and far more expensive per pixel. An approximation driven by a distortion field captures the visual signature that makes a black hole recognisable — the asymmetric ring and the way the far side of the disc appears to wrap above and below the shadow — at a fraction of the cost, and it stays interactive.
Treating it as a rendering problem rather than a physics problem keeps the project honest and keeps the scope small enough to finish. Adding genuine geodesic integration is a natural next step and a substantially different piece of work.
Implementation notes
The renderer is written in Python with OpenGL bindings and GLSL shaders, so the per-pixel loop runs entirely on the GPU while Python handles window creation, input and uniform updates. Shader compilation happens at start-up, which means the hot path contains no CPU-side per-pixel work at all.
Camera state is passed to the shader as uniforms each frame, so orbiting the view costs one uniform update rather than a rebuild of any geometry. Because nothing is precomputed, changing a mode changes only which branch of the fragment shader executes.
At a glance
- Real-time Rendering
- 5 Visualization Modes
- Interactive Camera
- Procedural Graphics