# Black Hole Observatory v1 — matter & spin

An interactive image of a stationary, opaque equatorial disk around a Kerr black
hole. This is an original numerical implementation, not a simulation of a
specific source or an evolving solution of the Einstein field equations.

## Geometry and observer

Set G=c=M=1. Radii are in GM/c², **half the Schwarzschild-radius unit used in v0**.
The dimensionless spin a ranges from 0 to 0.98. The horizon is
r₊ = 1 + √(1−a²). The observer is stationary at infinity, at inclination i=10°–85°
from the spin axis. Framing is the horizontal coverage of the asymptotic image
plane in M; it is not distance from the black hole.

For horizontal and vertical image coordinates α and β, the future-directed
photon constants divided by its energy are

    λ = −α sin i
    Q = β² + (α² − a²) cos² i

The calculation follows the ray backward from the observer. Let u=1/r and
μ=cos θ, and use a positive backward Mino parameter τ. The radial and polar
potentials are

    (du/dτ)² = 1 + (a² − λ² − Q)u² + 2[(λ−a)²+Q]u³ − a²Q u⁴
    (dμ/dτ)² = Q + (a² − λ² − Q)μ² − a² μ⁴

We differentiate these potentials to integrate second-order equations. This
passes radial and polar turning points without manual sign flips:

    u″ = (a²−λ²−Q)u + 3[(λ−a)²+Q]u² − 2a²Q u³
    μ″ = (a²−λ²−Q)μ − 2a² μ³

Initial conditions at infinity are u=0, u′=1, μ=cos i, μ′=β sin i.
Azimuth and coordinate time are not integrated: disk emission is stationary
and axisymmetric, so the image requires neither. This also avoids the polar
coordinate singularity in the azimuth equation. Kerr spin still enters the
geodesic potentials; this is not a Schwarzschild deflection with a skewed image.

## Disk and light

The disk occupies r_ISCO ≤ r ≤ 25 M, with prograde circular geodesic emitters.
The standard Kerr prograde ISCO expression is

    Z₁ = 1 + (1−a²)^(1/3) [(1+a)^(1/3) + (1−a)^(1/3)]
    Z₂ = √(3a² + Z₁²)
    r_ISCO = 3 + Z₂ − √[(3−Z₁)(3+Z₁+2Z₂)]

The first equatorial crossing inside this interval hits the opaque disk.
Crossings through its central gap or outside its outer edge continue tracing.
The two disk faces emit identically. There is no light in the background sky.
Thus a dark pixel may mean capture, a disk miss, negligible emissivity, or an
unresolved ray; it should not automatically be called the event horizon.

For angular velocity Ω=1/(r^(3/2)+a), the observed/emitted frequency ratio is

    g = 1/[uᵗ (1−Ωλ)]
      = √(1−3/r+2a/r^(3/2)) / [1+(a−λ)/r^(3/2)]

Bolometric intensity transfers as I_obs = g⁴ I_em. This combines gravitational
and orbital frequency shifts. Switching frequency shifts off sets g=1 for
presentation while preserving the geodesics. The straight-light comparison
uses a flat disk with neither capture nor frequency shifts.

## Deliberate presentation choices

The illustrative local emissivity is proportional to
(r/r_ISCO)^−3 [1−√(r_ISCO/r)], normalized to its peak and smoothly tapered to
zero between 20 and 25 M. It is **not** the relativistic Novikov–Thorne flux.
An optional small radial modulation adds visible texture. A warm display palette,
exposure, ACES-like tone curve, sRGB encoding, and optional screen-space glow
make structure visible. They are not a calibrated thermal spectrum or a
prediction of visible-light colors. Spin comparisons normalize each local
emissivity profile separately; they do not hold accretion rate or luminosity
fixed. The disk has no animated turbulence, hydrodynamics, or magnetic fields.
There are no jets, finite thickness, returning radiation, or evolving spacetime.

## Numerical implementation and limits

A GLSL3 fragment shader integrates each ray with RK4, step
h=0.025/max(1,√(α²+β²)), up to 1024 steps. Equatorial intersections are refined
with 12 bisections, each using an RK4 substep. Infinity is u<0; capture occurs
at u≥1/r₊. Nonfinite states, polar drift outside |μ|≤1.0001, and exhausted
step budgets are labeled **unresolved**, never silently treated as capture.
Unresolved rays render dark. Infinitely narrow higher-order images and
critical rays are not resolved by a finite step/pixel budget.

The browser performs two draws: the ray-traced image, then optional display
glow and color encoding. Dragging temporarily reduces pixel resolution; a
sharper still follows. Balanced/Sharp change pixel resolution only. The scene
renders on changes, not in an idle animation loop. No server GPU, native binary,
precomputed image atlas, or new deployment service is required.

## Reproducible checks

- `scripts/reference.py` independently integrates inverse radius and **polar
  angle θ**, using SciPy DOP853 (rtol 2e−11, atol 2e−12). It does not import the
  renderer's JS or GLSL. 224 rays cover four spins, four inclinations, both image
  sides, disk hits, escape, and capture.
- `scripts/test-physics.mjs` compares the CPU RK4 implementation against those
  references and checks analytic ISCO/redshift limits. Results are published in
  [data/validation.json](data/validation.json).
- The web browser suite runs the actual GLSL integration into a float render
  target and reads it back for comparison with the independent references.
  It also checks controls, straight-light comparison, image export, mobile
  layout/touch, errors, and teardown. GPU sample errors are attached to CI as
  `kerr-gpu-reference-check` in the browser test report.

These are sampled numerical checks, not global error bounds or a proof that
all pixels are accurate. CPU double precision and GPU float arithmetic differ.
The automated mobile tests emulate Chromium touch/layout; physical iPhone/Safari
performance is not established. Reported `cpuSubmitMs` measures JavaScript
submission only, **not GPU frame time**.

## Primary sources

- Gralla & Lupsasca, *The Null Geodesics of the Kerr Exterior* (2020),
  https://arxiv.org/abs/1910.12881 — separated null-geodesic potentials.
- Li, Zimmerman, Narayan & McClintock, *Multi-Temperature Blackbody Spectrum of a
  Thin Accretion Disk around a Kerr Black Hole* (2005),
  https://arxiv.org/abs/astro-ph/0411583 — relativistic disk transfer and the
  distinction from a full disk-spectrum model. This experiment does not
  implement KERRBB or its self-irradiation treatment.

Three.js is MIT-licensed; its license is included in `licenses/three.txt`.
All scene code and visual assets here are generated by Midkernel's experiment.
