From 87b089eb3526fefad484e059bfab5b8d39845bb7 Mon Sep 17 00:00:00 2001 From: xfy Date: Mon, 13 Jul 2026 10:04:44 +0800 Subject: [PATCH] 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. --- README.md | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/params.rs | 1 + 2 files changed, 77 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..68922ff --- /dev/null +++ b/README.md @@ -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`. diff --git a/src/params.rs b/src/params.rs index 008a374..8fae0a6 100644 --- a/src/params.rs +++ b/src/params.rs @@ -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,