Curved-Ray Renderer Architecture Master Outline¶
1) Executive Summary¶
This document is the code-grounded master outline for the curved-ray renderer in this repository.
- Current state: the runtime path is a Godot-driven renderer where curved rays
are generated as bounded segment chains (
RayBeamRenderer.RaySeg) and consumed by a two-pass film pipeline (GrinFilmCamera.RenderStep). - Current state: field and geometry broadphase data are snapshotted into
RendererCore.SceneSnapshot.SceneSnapshotand shared viaRendererCore.Common.FrameSnapshotBus. - Current state: pass-2 collision/narrowphase still uses Godot physics
(
IntersectRay,IntersectShape,CastMotion) with optionalGeometryTLAScandidate pruning. - Planned / TODO: internal triangle-level intersection (BLAS + internal narrowphase) is not wired yet.
What this engine is:
- A curved-ray film renderer embedded in Godot.
- A hybrid architecture where
RendererCoreowns snapshot/field/TLAS data structures while final collision is still delegated to Godot physics.
What this engine is not (today):
- Not yet a fully internal intersection stack.
- Not yet an end-to-end task-graph scheduler in
RendererCore/Scheduler. - Not yet a production "Core" backend that replaces the legacy film path.
What "curved rays are first-class" means in implementation terms:
- Rays are explicitly represented as segment sequences (
RaySeg) with:A,B,TraveledB, andRadiusBound. RadiusBoundis consumed by pass-2 envelope broadphase (Aabb3.FromSegment(...).Expand(...)).- Pass-1 integration can be physically-driven (
UseIntegratedField) with adaptive step sizing, not just straight-line + post bend.
Source anchors:
GrinFilmCamera.csRayBeamRenderer.csRendererCore/SceneSnapshot/SceneSnapshot.csRendererCore/Common/FrameSnapshotBus.cs
Academic / PhD-Level Target (New)¶
This architecture is explicitly intended to scale from interactive GRIN ray bending to research-grade gravitational optics:
- Baseline: GRIN-style curved-ray transport controlled by simple field parameters (what the engine already ships today).
- Upgrade: null-geodesic integration in arbitrary spacetime metrics (Schwarzschild/Kerr/wormholes), with numerical controls and invariants aligned with academic gravitational optics software.
Key principle for correctness: scene geometry remains Euclidean, while curvature lives in the ray transport law (GRIN effective-medium or metric/geodesic ODE). This matches the standard GR rendering pattern: integrate rays in a curved manifold; intersect rays against embedded geometry surfaces.
2) Current Architecture at a Glance¶
Godot scene tree
-> GodotAdapter.SnapshotBuilder.BuildFromGodotScene(...)
-> SceneSnapshot { Fields, FieldParams, FieldTLAS, Geometry, GeometryTLAS }
-> CurvatureBoundGrid (added by GrinFilmCamera.RenderFrameBackend)
-> FrameSnapshotBus.Set(snapshot, frameId)
GrinFilmCamera backend dispatch (per _Process when UpdateEveryFrame=true)
-> BackendMode.Legacy:
LegacyBackend.RenderFrame(snapshot)
-> GrinFilmCamera.RenderStep()
Pass 1 (Parallel.For): segment integration + optional pass1 hit probes
Pass 2 (Main thread): broadphase + Godot physics + shading + writeback
Upload Image -> ImageTexture -> TextureRect/FilmOverlay2D
-> BackendMode.Core:
CoreBackend.RenderFrame(snapshot) // snapshot summary print
LegacyBackend.RenderFrame(snapshot) // still renders output
-> BackendMode.Compare:
LegacyBackend.RenderFrame(snapshot) // TODO compare mode
Current state:
- Main entry is
GrinFilmCamera._Process -> RenderFrameBackend. - Snapshot is rebuilt every frame from the live Godot scene.
- Legacy film pipeline is still the output-producing path.
Source anchors:
GrinFilmCamera.csGodotAdapter/SnapshotBuilder.csRenderBackends/LegacyBackend.csRenderBackends/CoreBackend.cs
3) Core Design Principles (As Implemented)¶
Snapshot Immutability¶
- Current state:
SceneSnapshotproperties areinit-set and rebuilt each frame (SnapshotBuilder.BuildFromGodotScene). - Current state: consumers read snapshot arrays as immutable for the frame.
- Current state: immutability is by discipline/convention; arrays are not deep read-only wrappers.
Data-Oriented Layout¶
- Current state: field/geometry snapshot data are SOA arrays and packed buffers
(
FieldEntitySOA,GeometryEntitySOA,PackedParamBuffer). - Current state: TLAS node arrays are contiguous (
FieldTLAS.Nodes,GeometryTLAS.Nodes) for stack-based traversal.
Determinism and Threading¶
- Current state: snapshot extraction order is stabilized by sorting node paths
(
string.CompareOrdinal). - Current state: pass-1 is parallel per pixel; pass-2 remains main-thread due Godot physics API calls.
- Current state:
RenderStephas a re-entry guard (Interlocked). - Current state: optional SoftGate random probing uses
_rng.Randf(), so deterministic replay is not guaranteed when randomness is enabled.
Source anchors:
GodotAdapter/SnapshotBuilder.csRendererCore/SceneSnapshot/*.csRendererCore/Fields/FieldTLAS.csRendererCore/Geometry/GeometryTLAS.csGrinFilmCamera.cs
4) Module Map (Folders and Responsibilities)¶
RendererCore/*¶
SceneSnapshot/*: snapshot container and SOA/pod types.Fields/*: field enums, field evaluation, field TLAS, curvature bound grid.Geometry/*: geometry TLAS over world AABBs.Integrators/*: currently onlyStepPolicy(dt helper).Common/*: snapshot bus + debug overlay/log toggles.Accel/: currently empty.Scheduler/: currently empty.
Portability & Academic Upgrade Interfaces (New)¶
Goal: keep the current Godot integration working unchanged, while formalizing clear seams so the same core can run:
- inside Godot (interactive),
- in headless CLI regression tests,
- in other host environments long-term.
This is achieved by making ray transport + stepping engine-agnostic and treating Godot as a geometry query backend, not as the owner of physics.
1) Ray Transport / Physics Core Interfaces (RendererCore-owned)¶
IRayTransport (planned):
- Advances a ray state through a curvature model using a chosen integrator tier.
- Responsible for: step size control, invariant tracking (GR mode), and producing a
polyline/segment chain compatible with existing RaySeg consumption.
Ray state types (planned):
- RayState3: position + direction + parameterization (GRIN / 3D optical form)
- RayState4: spacetime position x^μ + wavevector/momentum k^μ + affine λ (GR / 4D form)
ITransportModel (planned) is the physics backend plugged into IRayTransport:
- GRIN / optical medium backend (scalar/tensor IOR)
- Metric / geodesic backend (Christoffel / Hamiltonian RHS)
- Optional Gordon/effective-medium adapter backend
2) Metric Interface for GR Mode (Research-grade)¶
IMetricField (planned):
- Metric(x) -> g_{μν}(x) (4x4 symmetric)
- Either:
- Christoffel(x) -> Γ^μ_{αβ}(x)
- or GeodesicRhs(state) -> derivatives for the ODE integrator
Implementation targets (non-exhaustive): - Minkowski (flat) - Schwarzschild - Kerr (Interstellar tier) - Morris–Thorne wormhole (chart/atlas compatible)
This interface is explicitly designed so academics can contribute metric modules without touching renderer frontends or collision backends.
3) Integrator Interface (Tiered)¶
IIntegrator (planned):
- Step(state, rhs, dt) with optional embedded error estimate
- Supports integrator tiers:
- Tier 0: heuristic adaptive (current behavior)
- Tier 1: RK45 / embedded error estimate
- Tier 2: symplectic/variational + constraint projection (GR null invariants)
IConstraintProjector (planned, GR-mode only):
- enforces/bounds null constraint drift:
g_{μν} k^μ k^ν = 0 within tolerance
4) Geometry Query Backend Interface (Host-owned)¶
IGeometryQueryProvider (planned):
- Narrowphase: segment raycast or swept segment test (existing Pass2 concept)
- Broadphase: overlap AABB / candidate ID collection (existing TLAS concept)
Godot provides one implementation:
- GodotGeometryQueryProvider wraps DirectSpaceState calls
Future implementations:
- BVHGeometryQueryProvider (internal triangle BVH / CPU)
- OfflineMeshQueryProvider (headless validation / batch renders)
This preserves the core idea: curvature affects ray transport; geometry remains Euclidean.
5) Camera Model Provider (Host-owned, Physics-owned math)¶
ICameraModelProvider (planned):
- returns camera rays in local frame
- GR mode can optionally provide tetrad-based emission and frequency bookkeeping
Godot provides: - camera pose + projection + per-frame properties
RendererCore provides: - the math for mapping local camera frame -> initial ray state (3D or 4D).
6) Minimal Adoption Strategy (No Big Refactor)¶
To avoid a disruptive rewrite:
- keep GrinFilmCamera.RenderStep() as orchestrator
- carve out a RendererCore.RenderBand(...) call that accepts:
- snapshot refs
- IRayTransport
- IGeometryQueryProvider
- camera rays provider
- output film buffer accessor
This can start as a thin wrapper around existing Pass1/Pass2 routines and gradually lift logic into RendererCore without breaking the Godot front-end.
Planned additions to support academic gravitational optics (without changing existing flow):
Relativity/*(planned): spacetime metric definitions and adapters.IMetricField(metric + connection / RHS).MetricAdapters(optional Gordon/effective-medium mapping where applicable).Transport/*(planned): engine-agnostic ray transport layer.IRayTransportthat advances a ray state using chosen integrator tier.CameraModel/*(planned): relativistic camera / tetrad frame support for correctness when rendering strong-field scenes.
Source anchors:
RendererCore/SceneSnapshot/SceneSnapshot.csRendererCore/Fields/FieldSystem.csRendererCore/Geometry/GeometryTLAS.csRendererCore/Integrators/StepPolicy.csRendererCore/Common/FrameSnapshotBus.cs
RenderBackends/*¶
- Backend interface and mode enum.
LegacyBackend: drivesGrinFilmCamera.RenderStep().CoreBackend: currently logs snapshot summary.BackendSelector: exists but is not the active dispatch path.
Source anchors:
RenderBackends/IRenderBackend.csRenderBackends/LegacyBackend.csRenderBackends/CoreBackend.csRenderBackends/BackendSelector.cs
GodotAdapter/*¶
- Godot scene extraction into
SceneSnapshot. - Field collection, parameter packing, TLAS builds.
- Geometry collection as world AABBs + Godot instance IDs.
Source anchors:
GodotAdapter/SnapshotBuilder.cs
Root-level Orchestrators / Runtime Nodes¶
GrinFilmCamera: backend dispatch, frame snapshot publish, film render loop, pass-1/pass-2 pipeline, budgets/watchdogs, telemetry.RayBeamRenderer: curved segment integration primitives and collision helper APIs used by film pass.FieldSource3D: authoring/runtime field node definition.FieldGrid3D: pass-1 acceleration cache (vector field grid).FieldProbe3D: runtime probe of snapshot field system + debug overlay output.FilmOverlay2D: 2D overlay renderer for debug rays/hit normals/bus items.PerfScope/PerfStats: timing/counter aggregation and log output.
Source anchors:
GrinFilmCamera.csRayBeamRenderer.csFieldSource3D.csFieldGrid3D.csFieldProbe3D.csFilmOverlay2D.csPerfScope.csPerfStats.cs
5) Data Model and Memory Layout¶
SceneSnapshot Shape¶
Current state (RendererCore.SceneSnapshot.SceneSnapshot):
InstanceSOA InstancesFieldEntitySOA FieldsPackedParamBuffer FieldParamsFieldTLAS FieldTLASGeometryEntitySOA GeometryGeometryTLAS GeometryTLASCurvatureBoundGrid CurvatureGrid
SOA Containers¶
Current state:
InstanceSOA: mesh/material IDs, object/world transforms, world bounds.GeometryEntitySOA: world bounds +GodotInstanceIds.FieldEntitySOA: metric/shape/curve enums, transforms, bounds, param offsets/lengths, flags.
Packed Parameters¶
Current state:
PackedParamBuffer.AppendBlock8(...)stores field params in blocks of 8:rInner, rOuter, amp, a, b, c, r0, r1.
TLAS Layers¶
Current state:
FieldTLASbuilt fromFieldEntitySOA.WorldBounds.GeometryTLASbuilt fromGeometryEntitySOA.WorldBounds.
Frame Rebuild vs Reuse¶
Current state:
- Rebuilt per frame: snapshot, field TLAS, geometry TLAS, curvature grid.
- Reused across frames: camera-owned pass buffers (
_segBuf, hit arrays, quick-ray caches, perf windows, optional field grid cache with cadence).
Important present limitation:
SnapshotBuildercurrently setsInstances = InstanceSOA.Empty(); instance transform SOA is defined but not populated in this path.
Source anchors:
RendererCore/SceneSnapshot/SceneSnapshot.csRendererCore/SceneSnapshot/InstanceSOA.csRendererCore/SceneSnapshot/GeometryEntitySOA.csRendererCore/SceneSnapshot/FieldEntitySOA.csRendererCore/SceneSnapshot/PackedParamBuffer.csGodotAdapter/SnapshotBuilder.cs
6) Coordinate Spaces and Transforms¶
Current state:
- Field evaluation is world-query driven:
FieldSystem.AccelAt(Vector3 pWorld, SceneSnapshot snapshot). - Field transforms are explicit per entity:
WorldFromLocal[]andLocalFromWorld[]. - Field radius/shape tests are evaluated in field-local space and converted back to world contribution.
- Geometry in snapshot is currently represented in world AABBs.
- Camera convention follows Godot: forward is
-Basis.Z.
Current state for instance transforms:
InstanceSOA.WorldFromObjectandObjectFromWorldare part of model but not currently populated bySnapshotBuilder.
Source anchors:
RendererCore/Fields/FieldSystem.csRendererCore/SceneSnapshot/FieldEntitySOA.csRendererCore/SceneSnapshot/InstanceSOA.csGodotAdapter/SnapshotBuilder.csRayBeamRenderer.cs
7) Fields and Metrics System¶
Field Entity Representation¶
Current state:
- Authored by
FieldSource3Dwith exported:MetricModel,FieldShapeType,FieldCurveType, radii, amplitude, flags, and curve coefficients. - Extracted by
SnapshotBuilderinto SOA arrays andPackedParamBuffer.
Metric Models¶
Current state (RendererCore.Fields.MetricModel):
GRIN = 0GordonMetric = 1
Current behavior:
FieldSystemflips local direction sign forGordonMetricvsGRIN.
Academic Optics Contract (New)¶
This engine supports (and will more explicitly formalize) two physically grounded but operationally distinct formulations of curved light transport:
1) Optical Medium / GRIN (3D)
- Rays follow stationary optical path (Fermat principle) through an index field n(x).
- Current implementation already author-controls behavior via simple GRIN parameters
(beta/gamma curves, radii, amplitude, per-field curve types).
- Planned: allow scalar n(x) and later anisotropic/tensor forms n_ij(x) for
higher fidelity mappings.
2) Spacetime Metric / Null Geodesics (4D)
- Rays follow null geodesics of g_{μν}(x) governed by the geodesic ODE:
d²x^μ/dλ² + Γ^μ_{αβ} dx^α/dλ dx^β/dλ = 0.
- Planned: integrate either in second-order form or in first-order Hamiltonian form
(recommended for invariant preservation).
Gordon / Effective-Medium Bridge (Clarification)¶
GordonMetric is treated as an adapter path:
in some cases, spacetime curvature can be expressed as an effective optical medium.
The architecture intends to support both:
- Direct metric/geodesic stepping (exact within numeric tolerance).
- Optional mapping to an equivalent GRIN-style transport model (for performance or authoring).
This preserves the existing “simple GRIN input parameters” workflow while enabling academic accuracy where required.
Shapes and Curves¶
Current state:
- Shapes:
SphereRadial,BoxVolume. - Curves:
Linear,Power,Polynomial,Exponential. FieldCurves.Eval(...)handles curve law evaluation.
Current limitations / TODO already in code:
FieldSystem:BoxVolumecurrently falls back to radial distance model.FieldSystem: flags behavior includes TODO for1/r^2mode details.
Curvature Bounds and Grids¶
Current state:
CurvatureBoundGrid.BuildAroundCamera(...)computes per-cellKmaxusing candidate fields viaFieldTLAS.QueryAabb.RayBeamRenderer.BuildRaySegmentsCamera_Pass1converts localKmaxinto segment envelope radius bound (RaySeg.RadiusBound).StepPolicy.ComputeDtexists and is used byFieldProbe3Dfor probe readouts.
Field Cache (FieldGrid3D)¶
Current state:
- Optional pass-1 vector field cache (
UseFieldGrid) rebuilt on cadence or field cache refresh; sampled before source fallback.
Source anchors:
FieldSource3D.csRendererCore/Fields/FieldModels.csRendererCore/Fields/FieldCurves.csRendererCore/Fields/FieldSystem.csRendererCore/Fields/CurvatureBoundGrid.csFieldGrid3D.csFieldProbe3D.cs
8) Curved Ray Representation and Integration¶
Ray State in Code¶
Current state:
- Segment struct:
RayBeamRenderer.RaySeg(A,B,TraveledB,RadiusBound). - Hit payload:
RayBeamRenderer.HitPayload. - Pass-1 hit metadata:
RayBeamRenderer.Pass1HitInfo.
Integration Method¶
Current state:
- Main pass-1 builder:
RayBeamRenderer.BuildRaySegmentsCamera_Pass1(...). - Uses explicit stepping over
StepsPerRaywith two paths: - Integrated path (
UseIntegratedField=true): update velocity by field acceleration and step adaptively. - Analytic bend path: parametric bend by
beta * t^gamma * bendScale. - Adaptive step controls:
StepLength,MinStepLength,MaxStepLength,StepAdaptGain, low-curvature boost controls.
Integrator Tiers (New; aligns with “PhD-grade” expectations)¶
The engine already uses curvature-aware adaptive stepping heuristics. The planned formalization is a tiered integrator system:
- Tier 0 (Interactive/Preview): current heuristic adaptive stepping (fast).
- Tier 1 (Research): embedded error-estimating integrators (e.g., RK45 / Dormand–Prince) with adaptive step based on local truncation error, not just |accel| heuristics.
- Tier 2 (Invariant-Preserving): Hamiltonian geodesic integration with symplectic/variational methods + constraint projection where needed.
Physical Invariants / Constraints (New)¶
For academic GR mode, ray state must remain null:
g_{μν} k^μ k^ν = 0 (within bounded tolerance).
The architecture will track and bound: - null constraint drift (and optionally project back onto constraint manifold) - monotonic affine parameter advance - error estimates and convergence (step-halving / tolerance sweeps)
“Interstellar-Class” Rendering Claim (Clarification)¶
Achieving Interstellar-style visuals requires: - accurate null geodesic integration in strong-field metrics (e.g., Kerr) - a physically correct camera model (observer frame / aberration / frequency shifts) - shading hooks for redshift and Doppler effects (can be incremental)
The current segment-chain pipeline (RaySeg) remains valid: geodesic transport changes
the stepping law, not the downstream broadphase/narrowphase consumption.
Segment Cadence and Envelopes¶
Current state:
- Segment emission cadence uses base
CollisionEveryNStepsand optional screen-space cadence adaptation. - Envelope radius is computed from curvature grid when available.
Chunking and envelope status:
- Current state: envelope-carrying segments are implemented (
RadiusBound). - Planned / TODO: dedicated chunk system from
Docs/spec_curved_ray_chunks.mdis not yet materialized as separate runtime chunk types.
Source anchors:
RayBeamRenderer.csGrinFilmCamera.csDocs/spec_curved_ray_chunks.md
9) Acceleration Structures and Intersection¶
TLAS in Runtime¶
Current state:
FieldTLAS: BVH over field AABBs, used for field candidate queries.GeometryTLAS: BVH over geometry AABBs, used as pass-2 candidate pruning.
BVH/BLAS Type Inventory¶
Current state:
RendererCore.Fields.BVHNodeinFieldTLAS.RendererCore.Geometry.GeometryBVHNodeinGeometryTLAS.- No BLAS triangle BVH implementation in
RendererCore/Accelyet.
Intersection API Boundary¶
Current state:
- Pass-1 generates segments and optional probe hits.
- Pass-2 performs broadphase + narrowphase using Godot physics:
IntersectRay,IntersectShape,CastMotion, and helper wrappers (SubdividedRayHit,SweepSegmentHit). - When geometry TLAS pruning is enabled, narrowphase hits are accepted only if collider ID is in TLAS-derived candidate instance IDs.
Validation vs production status:
- Current state: Godot physics is still production narrowphase.
- Planned / TODO: internal triangle-level intersection path to replace this.
Source anchors:
RendererCore/Fields/FieldTLAS.csRendererCore/Geometry/GeometryTLAS.csGrinFilmCamera.csRayBeamRenderer.csRendererCore/SceneSnapshot/GeometryEntitySOA.cs
10) Scheduling and Concurrency¶
Current state work partition:
- Frame is processed in row bands (
RowsPerFrameand adaptive row sizing). - Pass-1:
Parallel.Foracross pixels in current band. - Pass-2: sequential on main thread.
Current thread-safety strategy:
- Snapshot is read-only during
RenderStep. - Pass-1 writes per-pixel buffers (disjoint indices) and merges counters via
Interlocked. - Re-entry guard prevents overlapping
RenderStepinvocations.
RenderStep orchestration note (New; matches code):
GrinFilmCamera.RenderStep()is treated as the primary frame render trigger point and must remain a clean boundary between:- engine-agnostic transport (ideally
RendererCoreowned), and - engine-specific collision/query backends (Godot today).
This supports long-term portability to non-Godot frontends while preserving current behavior.
Current watchdogs and budgets:
UpdateEveryFrameBudgetMs,UpdateEveryFrameMaxRowsPerStep.RenderStepMaxMs,RenderStepMaxPixelsPerFrame,RenderStepMaxSegmentsPerFrame.- Multiple guard exits for stuck/no-progress/no-hit/no-candidate bands.
- SoftGate budgets and watchdog (
Pass2SoftGate*config set).
Planned / TODO:
RendererCore/Scheduleris currently empty; task-graph scheduler doc exists but is not the runtime backbone yet.
Source anchors:
GrinFilmCamera.csRenderBackends/LegacyBackend.csRendererCore/Scheduler/Docs/spec_scheduler_task_graph.md
11) Rendering Backends and Output¶
Current backend reality:
LegacyBackendis the rendering backend that produces film output.CoreBackendcurrently prints snapshot summary only.BackendMode.Corecurrently executes both core summary and legacy render.BackendMode.Comparecurrently falls back to legacy path.
Current output chain:
- Film buffer (
Image) updated toImageTextureeach render step. - Output to configured
TextureRect(FilmViewPath) or auto-created overlay. - Optional
FilmOverlay2Ddraws world ray/hit overlays + film gradient normals. DebugOverlayBusitems (for example fromFieldProbe3D) are consumed byFilmOverlay2D.
Postprocess/shader note:
- Shader files exist in repo, but this C# pipeline does not currently show a dedicated postprocess stage wiring them in runtime code.
Source anchors:
RenderBackends/LegacyBackend.csRenderBackends/CoreBackend.csRenderBackends/BackendMode.csGrinFilmCamera.csFilmOverlay2D.csRendererCore/Common/DebugOverlayBus.cs
12) Telemetry, Debugging, and Validation¶
Current telemetry:
XPrimeRay.Perf.FramePerf+PerfScopestage timing/counters.PerfStatsrolling-window frame summaries and invariant checks.- Frame/band render-health logging in
GrinFilmCamera.
Current debugging and validation helpers:
FieldProbe3DevaluatesFieldSystem.AccelAtagainst current snapshot bus state and draws overlay diagnostics.- Geometry prune audit and reject sampling instrumentation in pass-2.
FieldSource3Din-game debug shape rendering.RayBeamRendererdebug overlay +GetDebugRayBundlehandoff.RayVizandCurvedCameraare auxiliary debug/visual tools.
Validation Suite (New; “PhD-grade” requirements)¶
Add a reproducible validation harness that can run in-engine and offline. Minimum target scenarios:
Flat-space baselines: - straight-line rays (no field) match analytic results - segment envelope bounds remain stable and conservative
GRIN baselines: - known radial GRIN profiles reproduce expected qualitative lensing - convergence tests vs tighter tolerances / higher tier integrators
Schwarzschild benchmarks: - weak-field deflection matches analytic approximation in far-field - photon sphere behavior appears at expected radius (qualitative + numeric checks)
Kerr benchmarks (Interstellar tier): - compare selected rays against published Kerr geodesic references / datasets - regression snapshots for key camera poses and spin parameters
Wormhole metrics: - Morris–Thorne style throat lensing cases - chart transition / portal remap correctness tests (no coordinate singularity artifacts)
Numerical verification: - step-halving convergence where expected - bounded null-constraint drift in GR mode - optional constraint projection tests
The outcome is a credible claim that the renderer’s transport matches academic gravitational optics expectations to within configured tolerances.
Source anchors:
PerfScope.csPerfStats.csGrinFilmCamera.csFieldProbe3D.csFieldSource3D.csRayBeamRenderer.csRayViz.csCurvedCamera.cs
13) Roadmap (Reconciled to Current Code)¶
Charter Reality Check¶
- Previous charter said: renderer owns all production intersection.
- Code shows: pass-2 still uses Godot physics; internal TLAS is currently pruning/filtering, not full internal narrowphase.
-
Update needed: add internal triangle acceleration + intersection path before claiming full ownership.
-
Previous charter said: full end-to-end multithreading.
- Code shows: pass-1 is parallel, pass-2 is main-thread.
-
Update needed: move pass-2 off Godot physics dependency.
-
Previous charter said: scheduler/task graph subsystem.
- Code shows: scheduler folder is empty; scheduling logic is embedded in
GrinFilmCamera. - Update needed: migrate runtime scheduling to
RendererCore/Scheduler.
Implemented¶
- Scene snapshot extraction (
SnapshotBuilder) with field/geometry SOA. - Field and geometry TLAS builds and queries.
- Curvature bound grid creation around camera.
- Pass-1 curved segment integration with adaptive stepping and optional probes.
- Pass-2 broadphase policies + TLAS-gated Godot narrowphase.
- Budget/watchdog/telemetry framework in the film renderer.
In Progress¶
- Core backend migration (
CoreBackendexists but is summary-only). - Geometry TLAS pruning quality instrumentation (audit/fn/fp/reject samples).
- SoftGate policy tuning for quick-ray-miss recovery.
Planned Next¶
- Internal BLAS/triangle intersection path and removal of Godot as production narrowphase.
RendererCore/Schedulertask graph implementation.- Real compare mode in backend dispatch.
- Explicit runtime chunk system if needed beyond
RaySegenvelope usage.
Related specialized docs:
Docs/architecture_overview.mdDocs/spec_scene_snapshot_data_layout.mdDocs/spec_bvh_acceleration.mdDocs/spec_metric_models_grin_vs_gordon.mdDocs/spec_curved_ray_chunks.mdDocs/spec_scheduler_task_graph.md
14) Glossary¶
SceneSnapshot: immutable-for-frame container passed into rendering stages.SOA: struct-of-arrays data layout (FieldEntitySOA,GeometryEntitySOA).PackedParamBuffer: contiguous float buffer for field parameter blocks.TLAS: top-level AABB hierarchy over entities (FieldTLAS,GeometryTLAS).BLAS: lower-level triangle hierarchy; planned, not implemented in code.GRIN: metric model (MetricModel.GRIN) for optical gradient-index behavior.GordonMetric: metric model variant currently implemented as direction-sign inversion in field contribution logic.RaySeg: bounded curved segment used for pass-2 tests and envelopes.RadiusBound: conservative segment envelope radius used for geometry pruning.Pass-1: parallel segment integration stage.Pass-2: main-thread collision + shading stage.SoftGate: gated policy for extra subdivided checks on uncertain misses.FieldGrid3D: optional cached vector field for pass-1 acceleration sampling.CurvatureBoundGrid: camera-centered grid ofKmaxupper bounds.RenderHealth: rolling diagnostics for stalls, hit-rate, prune behavior.
4) Module Map (Folders and Responsibilities)¶
RendererCore/*¶
SceneSnapshot/*: snapshot container and SOA/pod types.Fields/*: field enums, field evaluation, field TLAS, curvature bound grid.Geometry/*: geometry TLAS over world AABBs.Integrators/*: currently onlyStepPolicy(dt helper).Common/*: snapshot bus + debug overlay/log toggles.Accel/: currently empty.Scheduler/: currently empty.
Source anchors:
RendererCore/SceneSnapshot/SceneSnapshot.csRendererCore/Fields/FieldSystem.csRendererCore/Geometry/GeometryTLAS.csRendererCore/Integrators/StepPolicy.csRendererCore/Common/FrameSnapshotBus.cs
RenderBackends/*¶
- Backend interface and mode enum.
LegacyBackend: drivesGrinFilmCamera.RenderStep().CoreBackend: currently logs snapshot summary.BackendSelector: exists but is not the active dispatch path.
Source anchors:
RenderBackends/IRenderBackend.csRenderBackends/LegacyBackend.csRenderBackends/CoreBackend.csRenderBackends/BackendSelector.cs
GodotAdapter/*¶
- Godot scene extraction into
SceneSnapshot. - Field collection, parameter packing, TLAS builds.
- Geometry collection as world AABBs + Godot instance IDs.
Source anchors:
GodotAdapter/SnapshotBuilder.cs
Root-level Orchestrators / Runtime Nodes¶
GrinFilmCamera: backend dispatch, frame snapshot publish, film render loop, pass-1/pass-2 pipeline, budgets/watchdogs, telemetry.RayBeamRenderer: curved segment integration primitives and collision helper APIs used by film pass.FieldSource3D: authoring/runtime field node definition.FieldGrid3D: pass-1 acceleration cache (vector field grid).FieldProbe3D: runtime probe of snapshot field system + debug overlay output.FilmOverlay2D: 2D overlay renderer for debug rays/hit normals/bus items.PerfScope/PerfStats: timing/counter aggregation and log output.
Source anchors:
GrinFilmCamera.csRayBeamRenderer.csFieldSource3D.csFieldGrid3D.csFieldProbe3D.csFilmOverlay2D.csPerfScope.csPerfStats.cs
7) Fields and Metrics System¶
Field Entity Representation¶
Current state:
- Authored by
FieldSource3Dwith exported:MetricModel,FieldShapeType,FieldCurveType, radii, amplitude, flags, and curve coefficients. - Extracted by
SnapshotBuilderinto SOA arrays andPackedParamBuffer.
Metric Models¶
Current state (RendererCore.Fields.MetricModel):
GRIN = 0GordonMetric = 1
Current behavior:
FieldSystemflips local direction sign forGordonMetricvsGRIN.
Shapes and Curves¶
Current state:
- Shapes:
SphereRadial,BoxVolume. - Curves:
Linear,Power,Polynomial,Exponential. FieldCurves.Eval(...)handles curve law evaluation.
Current limitations / TODO already in code:
FieldSystem:BoxVolumecurrently falls back to radial distance model.FieldSystem: flags behavior includes TODO for1/r^2mode details.
Curvature Bounds and Grids¶
Current state:
CurvatureBoundGrid.BuildAroundCamera(...)computes per-cellKmaxusing candidate fields viaFieldTLAS.QueryAabb.RayBeamRenderer.BuildRaySegmentsCamera_Pass1converts localKmaxinto segment envelope radius bound (RaySeg.RadiusBound).StepPolicy.ComputeDtexists and is used byFieldProbe3Dfor probe readouts.
Field Cache (FieldGrid3D)¶
Current state:
- Optional pass-1 vector field cache (
UseFieldGrid) rebuilt on cadence or field cache refresh; sampled before source fallback.
Source anchors:
FieldSource3D.csRendererCore/Fields/FieldModels.csRendererCore/Fields/FieldCurves.csRendererCore/Fields/FieldSystem.csRendererCore/Fields/CurvatureBoundGrid.csFieldGrid3D.csFieldProbe3D.cs
8) Curved Ray Representation and Integration¶
Ray State in Code¶
Current state:
- Segment struct:
RayBeamRenderer.RaySeg(A,B,TraveledB,RadiusBound). - Hit payload:
RayBeamRenderer.HitPayload. - Pass-1 hit metadata:
RayBeamRenderer.Pass1HitInfo.
Integration Method¶
Current state:
- Main pass-1 builder:
RayBeamRenderer.BuildRaySegmentsCamera_Pass1(...). - Uses explicit stepping over
StepsPerRaywith two paths: - Integrated path (
UseIntegratedField=true): update velocity by field acceleration and step adaptively. - Analytic bend path: parametric bend by
beta * t^gamma * bendScale. - Adaptive step controls:
StepLength,MinStepLength,MaxStepLength,StepAdaptGain, low-curvature boost controls.
Segment Cadence and Envelopes¶
Current state:
- Segment emission cadence uses base
CollisionEveryNStepsand optional screen-space cadence adaptation. - Envelope radius is computed from curvature grid when available.
Chunking and envelope status:
- Current state: envelope-carrying segments are implemented (
RadiusBound). - Planned / TODO: dedicated chunk system from
Docs/spec_curved_ray_chunks.mdis not yet materialized as separate runtime chunk types.
Source anchors:
RayBeamRenderer.csGrinFilmCamera.csDocs/spec_curved_ray_chunks.md
10) Scheduling and Concurrency¶
Current state work partition:
- Frame is processed in row bands (
RowsPerFrameand adaptive row sizing). - Pass-1:
Parallel.Foracross pixels in current band. - Pass-2: sequential on main thread.
Current thread-safety strategy:
- Snapshot is read-only during
RenderStep. - Pass-1 writes per-pixel buffers (disjoint indices) and merges counters via
Interlocked. - Re-entry guard prevents overlapping
RenderStepinvocations.
Current watchdogs and budgets:
UpdateEveryFrameBudgetMs,UpdateEveryFrameMaxRowsPerStep.RenderStepMaxMs,RenderStepMaxPixelsPerFrame,RenderStepMaxSegmentsPerFrame.- Multiple guard exits for stuck/no-progress/no-hit/no-candidate bands.
- SoftGate budgets and watchdog (
Pass2SoftGate*config set).
Planned / TODO:
RendererCore/Scheduleris currently empty; task-graph scheduler doc exists but is not the runtime backbone yet.
Source anchors:
GrinFilmCamera.csRenderBackends/LegacyBackend.csRendererCore/Scheduler/Docs/spec_scheduler_task_graph.md
12) Telemetry, Debugging, and Validation¶
Current telemetry:
XPrimeRay.Perf.FramePerf+PerfScopestage timing/counters.PerfStatsrolling-window frame summaries and invariant checks.- Frame/band render-health logging in
GrinFilmCamera.
Current debugging and validation helpers:
FieldProbe3DevaluatesFieldSystem.AccelAtagainst current snapshot bus state and draws overlay diagnostics.- Geometry prune audit and reject sampling instrumentation in pass-2.
FieldSource3Din-game debug shape rendering.RayBeamRendererdebug overlay +GetDebugRayBundlehandoff.RayVizandCurvedCameraare auxiliary debug/visual tools.
Source anchors:
PerfScope.csPerfStats.csGrinFilmCamera.csFieldProbe3D.csFieldSource3D.csRayBeamRenderer.csRayViz.csCurvedCamera.cs
14) Relativistic Optics, Metrics, and Wormholes¶
Goal: make the engine academically credible for gravitational optics by defining a metric-first path for null geodesics, while retaining the existing GRIN/field pipeline as a practical/artist-friendly control layer.
14.1 Key Principle: “Euclidean scene, non‑Euclidean light”¶
- Geometry/colliders can remain standard Euclidean meshes (for gameplay + authoring).
- The light transport is governed by an effective spacetime / optical metric that bends rays (null curves) through the same Euclidean world positions.
- This matches how most production GR lensing renderers work: they integrate geodesics in a chosen coordinate chart and sample scene content along the ray.
14.2 Physics alignment levels (Research Mode tiers)¶
Tier 0 (Current, “GRIN-Field”): - Rays bend under a configurable field rule (beta/gamma, integrated acceleration, step adapt). Good for art, intuition, and controllable DOEs.
Tier 1 (Optical Metric / Gordon Metric): - Interpret curvature field as a spatially varying refractive index and/or moving medium (Gordon metric). - Required: a canonical conversion contract: (field params) → (n(x), v(x)) → effective metric g_eff(x).
Tier 2 (Full GR Metric): - Integrate null geodesics from explicit g_{μν}(x) (Schwarzschild, Kerr, weak-field PN, custom numerically defined metrics). - Required: Christoffel symbols Γ^μ_{αβ}(x) and a null-constraint enforcement strategy.
Tier 3 (Exotic / Wormhole Metrics): - Implement a small library of wormhole metrics (e.g., Morris–Thorne-style spherically symmetric static wormhole) as coordinate charts. - Rendering does not require non-Euclidean meshes; it requires: - a coordinate mapping / chart definition, - geodesic integration through that chart, - and sampling content from one or more “regions” (mouth A / mouth B) via mapping.
14.3 Integrators: “PHD level” method inventory (engine should expose them)¶
Engine should provide a unified integrator interface with these options: - Fixed-step explicit integrators: Euler (debug), Midpoint, RK2, RK4. - Adaptive embedded Runge–Kutta: RKF45 / Dormand–Prince RK45 (error estimate + dt control). - Symplectic / geometric integrators (where applicable): Verlet / Stormer–Verlet, implicit midpoint (energy behavior). - Geodesic-specific forms: - Hamiltonian formulation for null geodesics (canonical momenta p_μ; integrate Hamilton’s equations). - First integrals for common metrics (Schwarzschild/Kerr constants of motion) to reduce drift. - Constraint handling: - null constraint g_{μν} u^μ u^ν = 0 enforced via projection, renormalization, or constrained integrator step.
Deliverable target: - A single “RayIntegrator” contract with: State, Step(dt), ErrorEstimate(dt), and optional ConstraintProject(). - Current “StepPolicy” becomes one implementation; GR integrators become additional implementations.
14.4 Wormhole modeling (what we need to add)¶
You do not need “non-Cartesian scene meshes.” You need non-trivial coordinate mapping and metric definitions: - Metric: pick a wormhole line element (static spherically symmetric is easiest). - Charts/Regions: define mouth A and mouth B as separate coordinate patches (or a single patch with mapping). - Ray transport: integrate geodesics through the metric; when the ray crosses the throat, map its coordinates to the other region. - Sampling: query fields/geometry in the appropriate region’s scene snapshot or via portal mapping.
Proposed engine abstraction:
- IMetricField (returns g_{μν} and optionally Γ or ∂g).
- IChartMap (maps between Euclidean world (x,y,z,t) and chart coordinates; supports portal crossings).
- IRaySampler (samples scene content along a ray, including “which region” rules).
14.5 Twistor/spinor note (position in the roadmap)¶
- Twistors/spinors can be treated as an alternative representation of rays and null directions (especially useful for Kerr and conformal structures).
- They are not strictly required to render GR lensing, but they can improve stability/efficiency and connect to conformal compactifications (Penrose-style).
- Roadmap: add a “representation layer” where a ray may be stored as (x^μ, p_μ) Hamiltonian state or a spinor/twistor state, while preserving the same integrator/sampler interfaces above.
15) Research Mode Toggle (spec)¶
Purpose: allow switching between production/gameplay constraints and research/validation constraints without touching gameplay-facing defaults.
Required components:
- ResearchModeConfig (authoritative toggle + policy)
- Enabled
- Preset (e.g., Off / Validate / PaperMatch / StressTest)
- LoggingVerbosity
- DeterminismMode (seeded RNG, disable random probes, fixed dt, etc.)
- ResearchModeOverrides (override values for EffectiveConfig)
- strong typing, explicit “OverrideX” bool flags
- override groups: Film, Broadphase, RayMarch, SoftGate, Budgets, Debug
Integration point (code):
- GrinFilmCamera.ResolveEffectiveConfig(out EffectiveConfig cfg) must call:
- ResearchModeOverrides.Apply(ref cfg, ResearchModeConfig cfgResearch, sourceContext: "GrinFilmCamera")
- Must log a one-line “ResearchMode active” banner when enabled, with a stable hash of the override set.
Validation behaviors to include: - Option to disable all stochastic choices (SoftGate randomness) for repeatable runs. - Option to run a “truth pass” (full overlap + no pruning) on a sampled subset for FP/FN estimates. - Option to dump ray states for a small set of pixels for offline comparison.
15) Research Mode Toggle Spec¶
Goal¶
Research Mode is a configuration + validation contract that makes xPRIMEray suitable for academic / PhD-level gravitational optics workflows:
- explicit numeric tolerances (step size, error bounds)
- invariant tracking knobs (e.g., null constraint drift in metric mode)
- reproducibility controls (deterministic scheduling, fixed seeds)
- a test harness that can be compared against published results
Public Configuration¶
The portable config types live in:
RendererCore/Config/ResearchModeConfig.csRendererCore/Config/ResearchModeOverrides.cs
In Godot, the camera exposes inspector-facing overrides under Research Mode, then merges them
into EffectiveConfig.Research inside GrinFilmCamera.ResolveEffectiveConfig(...).
Tiers¶
- Tier0_Preview: current behavior; heuristic stepping; performance first.
- Tier1_ErrorBounded: declares per-ray tolerance goals; enforces dt bounds and work caps; prepares the integrator upgrade path to embedded error estimation (RK45) while remaining backwards compatible.
- Tier2_InvariantPreserving: adds invariant tracking + (optional) constraint projection for metric transport; target mode for “academically comparable” claims.
Determinism Rules¶
When DeterministicMode=true:
- disable probabilistic probes (
SoftGate.RandomProbeChance = 0) - process work in deterministic order (band/row order)
- avoid nondeterministic reductions for metrics and validation
Minimal Runtime Application (current code)¶
Today (pre-RK45), Research Mode already applies conservative constraints without re-architecting:
- clamps marcher step length using
DtMin/DtMax - caps
StepsPerRayviaMaxStepsPerRay - disables probabilistic probes in deterministic mode
These guardrails let us start building reproducible benchmark suites immediately, then swap in stronger integrators later.
Validation Harness (planned)¶
Research Mode supports a validation suite selector (quick sanity → full regression → metric benchmarks) with a structured report output. Benchmarks should include:
- Flat-space straight-ray tests
- GRIN lens regressions (known profiles)
- Schwarzschild lensing and photon-sphere qualitative behavior
- Kerr lensing spot checks
- Wormhole throat continuity tests