GR 4D ray tracing — Phase 0 prototype
minkowski_sky is a deliberately small, CPU-only, single-frame Phase 0
benchmark. It renders point sources from a sky catalog through an analytic
backend. It is not a sky texture: each source remains a direction, temperature,
and amplitude until its sub-pixel Gaussian PSF is splatted.
Build and render the default 1280 x 720 image:
make run
The program first creates assets/sky_grid_5deg.csv when it is missing. The
synthetic catalog places stars every 2 degrees on the union of longitude and
latitude lines spaced 10 degrees apart; the two poles are stored only once.
The eight octants (four 90-degree longitude sectors in each hemisphere)
alternate red temperature_K = 3000 and blue temperature_K = 12000.
Red stars use amplitude = 1; blue stars use amplitude = 0.00141095580387,
which equalizes their CIE/linear-sRGB luminance under the renderer's blackbody
integration. Longitude boundaries belong to the sector to their east and the
equator to the northern hemisphere, so boundary stars have a deterministic
color.
The output is a binary PPM at output/imgs/minkowski_sky.ppm; it can be inspected by
most image viewers or converted to PNG with ImageMagick.
Movie PNG sequence (Phase A)
Movie mode consumes a canonical observer-track CSV rather than a fixed camera.
Each row stores coordinate time, proper time, Cartesian position, and the full
four-by-four tetrad (21 columns total). Generate the first reproducible
Minkowski benchmark—two coordinate seconds at 30 fps, accelerating from rest
to about 0.95c—then render its numbered PNG frames:
make clean && make ENABLE_PNG=1
mkdir -p output/imgs
./build/minkowski_sky --write-minkowski-accel-track output/minkowski_accel_2s.csv \
--duration 2 --fps 30 --proper-acceleration 1.52
./build/minkowski_sky --observer-track output/minkowski_accel_2s.csv \
--frames-dir output/imgs --frames-prefix minkowski_accel \
--start-time 0 --duration 2 --fps 30
This writes minkowski_accel_000000.png through
minkowski_accel_000060.png. The renderer treats the CSV as its observer
input; the acceleration generator is only a reproducible flat-spacetime test
fixture. The current movie path still renders frames independently while the
time-slab/RayPool scheduler is implemented next, so it must not yet be used
as a performance measurement for numerical-relativity data.
PNG output is optional so the default build has no libpng dependency. Build
with make ENABLE_PNG=1, then select it with a .png output path:
make clean && make ENABLE_PNG=1
mkdir -p output/imgs
./build/minkowski_sky --output output/imgs/minkowski_sky.png
Run the flat-spacetime geodesic regression with:
make test
This also checks that the Kerr--Schild metric remains finite at r=2M and
that the central ray from the default Schwarzschild camera is classified as
captured.
Build an independent analytic Schwarzschild executable in Cartesian ingoing Kerr--Schild coordinates (regular at the horizon), then render the test catalog to PNG:
make clean && make SPACETIME=schwarzschild ENABLE_PNG=1
mkdir -p output/imgs
./build/schwarzschild_sky --catalog assets/sky_grid_5deg.csv \
--width 640 --height 360 --coarse-cell-pixels 8 --fov-deg 60 \
--output output/imgs/schwarzschild_test_catalog.png
SPACETIME=minkowski (the default) and SPACETIME=schwarzschild select source
files at compile time, so each executable contains exactly one metric provider.
The Schwarzschild demonstration uses mass M=1, a static camera at Cartesian
Kerr--Schild position (30, 0, 0), directed at the hole, escapes at r=256,
and declares capture at r=1.5, safely inside the horizon at r=2. Those
rendering thresholds are Phase-1 demonstration values, not settled production
refinement or integration settings.
For a local radial boost relative to that static camera, pass
--observer-inward-speed V, where 0 <= V < 1 is measured in the static
observer's orthonormal frame and positive values point toward the hole. The
default is 0, preserving the static camera.
For rays that asymptote to the future horizon in coordinate-time backward
integration, the Schwarzschild demo also terminates at
log(alpha p^0) = 8. This is the normalized-momentum horizon diagnostic
already evolved by the integrator; it is disabled by default and does not
replace the AH-calibrated spatial capture criterion planned for nmesh data.
Useful options:
./build/minkowski_sky --width 1920 --height 1080 --fov-deg 30 \
--catalog assets/sky_grid_5deg.csv --output output/imgs/frame.ppm
./build/minkowski_sky --catalog assets/2mass/processed/2mass_psc_m31_0p5deg_stars.csv \
--look-ra-deg 10.6847083 --look-dec-deg 41.26875 --fov-deg 1.8 \
--exposure 1e15 --output output/imgs/2mass_m31.ppm
./build/minkowski_sky --catalog assets/2mass/processed/2mass_psc_m44_1p0deg_stars.csv \
--look-ra-deg 129.99165 --look-dec-deg 19.54139 --fov-deg 2.0 \
--exposure 1e15 --width 1920 --height 1920 --output output/imgs/2mass_m44.ppm
./build/minkowski_sky --write-catalog assets/sky_grid_5deg.csv
The camera is a fixed inertial observer at coordinate position (0,0,0),
with a tetrad whose forward direction is coordinate -Z and whose vertical
direction is +Y. The frame first triangulates the image plane, then traces
only its vertices backwards. Escaped endpoints form a triangulation on the
source sky. For every locally invertible triangle, catalog stars inside its
spherical source triangle are interpolated back to the image triangle and
splatted as PSFs. Consequently multiple image triangles naturally create
multiple images of the same star.
The ray state evolves (x^i, Pi_i, log(alpha p^0)) in coordinate time with
RK4 using the 3+1 equations in Bohn et al. II.A, until the spacetime backend
classifies the ray. spacetime.c is the only module containing the Minkowski
metric or its infinity criterion; frame, observer, and integrator use only
SpacetimeSource and MetricData. The initial regular mesh size is exposed
as --coarse-cell-pixels; it is a Phase-0 sampling knob, not a settled
production refinement threshold.
--look-ra-deg and --look-dec-deg rotate that fixed tetrad so its forward
axis is the corresponding catalog direction; their defaults reproduce the
original -Z view. --exposure converts a catalog's physical flux
normalization to the prototype HDR scale. Its default preserves the synthetic
catalog benchmark; a 2MASS blackbody normalization in steradians requires a
much larger display exposure such as the example above. The optics path
integrates each fitted Planck spectrum through CIE 1931 color-matching functions
and converts the resulting radiance to linear sRGB; it does not use an empirical
color-temperature RGB approximation.
Point sources use a flux-normalized circular Moffat PSF by default
(--psf-fwhm-pixels 2.7 --psf-moffat-beta 4.5). The FWHM matches the former
1.15-pixel Gaussian core while the Moffat wings remain continuous; both values
are display/optics calibration parameters.
Pass --draw-mesh to alpha-composite image-plane triangle edges as
one-pixel-wide 0.5 linear-gray diagnostic lines at 0.5 opacity. The line
rasterizer uses coverage-based antialiasing.