docs: README + silence reserved-field dead-code warning

README documents the renderer, run instructions (desktop + web), controls,
how the geodesic pipeline works, performance notes, and Phase 2 (Kerr) as
future work. Allow dead_code on BlackHoleParams since render_scale + spin
are intentionally reserved for Phase 2.
This commit is contained in:
xfy 2026-07-13 10:04:44 +08:00
parent 76d302b4e4
commit 87b089eb35
2 changed files with 77 additions and 0 deletions

76
README.md Normal file
View File

@ -0,0 +1,76 @@
# singularity-rs
A real-time, physically-motivated **Schwarzschild black-hole renderer** in [Bevy](https://bevyengine.org) 0.19. Each pixel geodesic-ray-traces curved spacetime, producing gravitational lensing, the Einstein ring, a Doppler-beamed accretion disk, a lensed starfield, and optional lensed planets, a spacetime-curvature (Flamm) grid, and a cubemap skybox. Runs on **desktop** and the **web** (WebGPU).
The visual target is Gargantua from *Interstellar*: a black shadow surrounded by a tilted, glowing accretion disk whose back side is lensed up and over the hole (and down underneath), with one side brighter from relativistic Doppler beaming.
## Run
**Desktop** (Vulkan / Metal / D3D12):
```sh
cargo run --release
```
**Web** (WebGPU — Chrome, Edge, recent Firefox/Safari):
```sh
cargo install --locked trunk
rustup target add wasm32-unknown-unknown
trunk serve
# open http://127.0.0.1:8080
```
Release web build: `trunk build --release`. On a browser without WebGPU, the page shows a fallback message instead of a blank canvas.
## Controls
- **Drag** (mouse) — orbit the camera around the hole.
- **Scroll** — zoom (changes distance / impact parameter).
- **Controls panel** (top-left) — live-tune every parameter:
- **Camera** — distance, yaw, pitch, FOV.
- **Accretion Disk** — inner/outer radius, tilt, brightness, rotation speed.
- **Doppler** — enable + strength of the relativistic beaming asymmetry.
- **Renderer** — integrator step count (the main quality/perf lever).
- **Background** — procedural star intensity, optional cubemap skybox intensity.
- **Grid** — toggle the lensed Flamm-paraboloid curvature grid + density.
Orbit input is automatically disabled while the cursor is over the panel.
## How it works
A single full-screen quad carries a custom `Material2d` whose fragment shader, for every pixel:
1. Generates a primary ray from the camera basis + FOV.
2. Integrates the ray through Schwarzschild spacetime with RK4, applying the discretized bending acceleration `a = -1.5·Rs·h²/r⁵ · pos` (`h` = angular momentum).
3. At each step tests the bent segment against the accretion disk (equatorial plane), lensed planets (storage buffer), and the Flamm paraboloid grid surface — compositing hits front-to-back.
4. Terminates on capture (`r < Rs`, the shadow emerges naturally at the critical impact parameter `b_crit = 3√3/2·Rs ≈ 2.598`) or escape (samples the procedural starfield / cubemap along the bent final direction).
The disk is tilted relative to the camera, so the back of the disk is lensed over the top and under the bottom of the shadow — the characteristic "halo." Doppler beaming brightens the approaching side.
The CPU-side physics (`src/physics.rs`) mirrors the integrator and is unit-tested: `b < b_crit` rays are captured, `b > b_crit` rays escape.
## Performance
Defaults target ~60 FPS at full resolution on a discrete/integrated GPU (developed on Apple M4). On web, defaults drop to `steps=200` for interactivity. If you need more FPS, lower **Steps** in the Controls panel.
Note: the `render_scale` parameter exists but is **not wired to a real sub-resolution render target in Phase 1** (the full-screen quad always renders at window resolution). It is reserved for future work; **Steps** is the real performance lever today.
## Project layout
```
src/
main.rs app entry, plugin wiring
camera.rs orbit controller (yaw/pitch/zoom) + WantsPointer
params.rs BlackHoleParams (tunable, mirrored to GPU each frame)
physics.rs CPU mirror of the geodesic integrator (unit-tested)
ui.rs egui Controls panel (collapsible sections)
web.rs wasm glue: WebGPU detection + fallback message
scene/planets.rs Planet component + storage-buffer upload
render/ BlackHolePlugin, material, fullscreen quad
assets/shaders/ WGSL: ray gen, Schwarzschild RK4, disk, stars, planets, grid, skybox
docs/superpowers/ design spec + implementation plan
```
## Status
**Phase 1 (Schwarzschild, this codebase)** — complete: shadow, tilted Doppler accretion disk with lensed Einstein halo, lensed starfield, lensed planets, lensed Flamm grid, optional cubemap skybox, live egui controls, desktop + web/WebGPU.
**Phase 2 (Kerr / true Gargatua) — future work.** Replace the Schwarzschild integrator with the Kerr metric (Boyer-Lindquist, adaptive RK4, spin parameter) for frame-dragging and ergosphere asymmetry. Same scene elements, camera, params, and UI carry over; only the integrator core swaps. See `docs/superpowers/specs/2026-07-09-interstellar-blackhole-design.md`.

View File

@ -3,6 +3,7 @@ use bevy::prelude::*;
/// All tunable black-hole parameters. Edited by the egui panel (Task 17),
/// mirrored into BlackHoleUniforms each frame (Task 7).
#[derive(Resource, Clone)]
#[allow(dead_code)] // render_scale + spin are reserved for Phase 2 (Kerr) / future work
pub struct BlackHoleParams {
// Physics (natural units, Rs = 1)
pub rs: f32,