Skip to content

ethank5149/nulltracer

Repository files navigation

Nulltracer

GPU-accelerated null geodesic ray tracing through Kerr–Newman spacetime — a CUDA simulator that renders the visual appearance of rotating, electrically charged black holes, validated against Event Horizon Telescope measurements of M87*.

Nulltracer rendering of a Kerr black hole with accretion disk

License: MIT CUDA 12.x Python 3.8+ float64 precision


What it is

Nulltracer is a from-scratch general-relativistic ray tracer. Each pixel is a CUDA thread integrating a null geodesic backward through curved spacetime in the Kerr–Newman metric (Boyer–Lindquist coordinates) at full float64 precision. The output is what an external observer would actually see — black hole shadow, photon rings, gravitationally lensed background, Doppler-boosted accretion disk, and frame-dragging asymmetry — for any combination of spin (a), charge (Q), and observer inclination (θ).

It's split into a CUDA + FastAPI render server and a thin browser client; the server does all the physics, the client just shows pictures and turns sliders.

Gallery

Schwarzschild (a = 0) Near-extremal Kerr (a = 0.99) Kerr–Newman charge sweep

Why this project

Most public black-hole "ray tracers" cut corners — Schwarzschild only, low-order integration, fudged shadows, no quantitative validation. Nulltracer was built to do the full Kerr–Newman case end-to-end on the GPU and to be checkable against real observational constraints. The hero deliverable is a Jupyter notebook (nulltracer.ipynb) that compares simulated M87* shadow diameters against the Event Horizon Telescope Paper VI measurement of 42 ± 3 μas.

Validation against EHT Paper VI

Physics engines are easy to make plausible and hard to make right. The repository ships a validation suite — eht_validation.py, compare.py — that benchmarks rendered output against published constraints:

  • Shadow diameter at M87* parameters (M = 6.5 × 10⁹ M☉, D = 16.8 Mpc, i ≈ 17°) compared to EHT's 42 ± 3 μas band
  • Bardeen analytic shadow boundary (closed-form Kerr critical curve) as ground truth for the spin sweep
  • ISCO radii (Kerr–Newman closed form) cross-checked against numerical orbit-stability tests
  • M-to-μas unit conversion following the EHT Paper VI conventions

The Schwarzschild limit gives 10.39 M ≈ 39.7 μas at M87* distance — within the EHT band. Spin-dependent results and the full validation report are in nulltracer.ipynb.

Current status. The geodesic engine, Bardeen formulas, and unit conversion are internally consistent; shadow-extraction now uses background-agnostic classify_shadow for reliable validation across all background modes. Spin-sweep results are ready for publication.

How it works

Spacetime. Kerr and Kerr–Newman metrics in Boyer–Lindquist coordinates with a μ = cos(θ) substitution for robust pole handling.

Integrators. RK4, Yoshida 4th/6th/8th-order symplectic, and adaptive Runge–Kutta–Dormand–Prince (RKDP8). Symplectic methods preserve phase-space structure for long-time stability; RKDP8 wins on accuracy-per-step for hard rays near the horizon.

Kernels. CuPy RawKernel C++ launched one-thread-per-pixel. All geodesic state evolves in float64. Background sampling uses equal-area sphere tiling to eliminate polar pinching; cube-map projection is supported for star fields.

Pipeline. FastAPI accepts parameters → CuPy kernel renders the frame → LRU cache keyed on parameter hash returns it as JPEG/WebP. Single-worker asyncio.Lock serializes GPU access.

Client. A vanilla-JS browser front-end probes /health on the same origin and shows the rendered frame; settings panel exposes a, Q, θ, integrator choice, step count, and quality preset.

Quick start

# CUDA 12.x + NVIDIA Container Toolkit required
git clone https://github.com/ethank5149/nulltracer && cd nulltracer
docker compose up -d
# open index.html in your browser

For full deployment options (Caddy reverse proxy, Unraid template, local dev), see DEPLOYMENT.md.

Architecture

nulltracer/
├── nulltracer.ipynb           # Hero deliverable: EHT validation notebook
├── index.html, js/, styles.css  # Thin browser client
├── server/
│   ├── app.py                 # FastAPI: /render, /health
│   ├── renderer.py            # CuPy RawKernel orchestration
│   ├── isco.py                # Kerr–Newman ISCO (closed form)
│   ├── eht_validation.py      # EHT Paper VI comparison suite
│   ├── compare.py             # Bardeen analytic shadow comparator
│   └── kernels/
│       ├── geodesic_base.cu   # Metric + Hamiltonian + RHS
│       ├── disk.cu            # Doppler-boosted accretion disk
│       ├── backgrounds.cu     # Stars / checker / colormap
│       └── integrators/       # rk4, rkdp8, yoshida4/6, kahan_li8
├── docker-compose.yml, Dockerfile
└── ARCHITECTURE.md            # Detailed technical write-up

For the full architecture write-up, see ARCHITECTURE.md.

Version history

Version Tag Key changes
v0.9 v0.9 Current. Polished Kerr–Newman release
v0.8 v0.8 Kerr–Newman extension (electric charge parameter)
v0.7 v0.7 Adaptive stepping refinements
v0.6 v0.6 μ = cos(θ) coordinate substitution for pole handling
v0.5 v0.5 Smooth regularization and cube-map projection
v0.4 v0.4 Numerical stability improvements
v0.3 v0.3 Equal-area sphere tiling (fixes polar pinching)
v0.2 v0.2 UX overhaul: legend, settings panel, multiple backgrounds
v0.1 v0.1 Refactored to separated first-order equations (~40% faster)
v0.0.1 v0.0.1 Initial Kerr black hole with Hamiltonian RK4 integration

git checkout v0.X to view any release.

Requirements

Server. Python 3.8+, NVIDIA GPU with CUDA 12.x (RTX 3090 / A100 / H100 tested), cupy-cuda12x. Docker + NVIDIA Container Toolkit recommended.

Client. Any modern browser (Chrome 56+, Firefox 51+, Safari 15+, Edge 79+). No local GPU required.

Citation

If this code or the validation methodology is useful in your work, please cite it:

@software{knox_nulltracer_2026,
  author  = {Knox, Ethan},
  title   = {Nulltracer: GPU-accelerated null geodesic ray tracing in Kerr–Newman spacetime},
  year    = {2026},
  url     = {https://github.com/ethank5149/nulltracer},
  version = {0.9}
}

License

Released under the MIT License.

Author

Ethan Knox — B.S. Physics, B.S. Mathematics, Purdue University Champaign, IL · github.com/ethank5149

About

GPU-accelerated ray tracing through Kerr-Newman spacetime with CUDA and Python

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors