6.3 KiB
AGENTS.md
项目目标
本仓库要构建一个离线、以物理正确性为优先的数值相对论时空视频渲染器。最终目标是把双黑洞(BBH)并合等动态数值相对论(NR)演化输出的真实四维时空渲染为 4K 视频。
渲染器必须直接消费时间依赖的 4D metric,对每条相机光线进行向过去的 null geodesic tracing;它不是仅渲染静态快照、波形或标量诊断的工具。第一阶段只处理两种 ray 终态:被黑洞捕获,或逃逸到无穷远天球。局域物质辐射、吸积盘、流体和等离子体均不在当前范围内。
设计依据是 nr_spacetime_movie_renderer_design.md。实现前应先阅读与修改内容相关的章节;该文档是架构和物理取舍的权威来源。
不要偏离的方向
- 不以实时性能、游戏式视觉近似或 ShaderToy 式效果为目标。
- frozen snapshot 只能作为数值演化代码内的廉价诊断,不能替代最终的动态 4D 渲染。
- 不把恒星背景预烘焙成 RGB 天球纹理;恒星是带方向、温度和振幅的点源 catalog。
- 相机不是固定三维坐标,而是 worldline 加 tetrad 的预生成轨迹。
- 第一版只做 CPU;先验证物理与数据流,再考虑 GPU。
- 不为复杂 OO/class hierarchy 增加抽象。首选 C 的
struct、明确 ownership、函数表和连续数组。
核心架构约束
时间组织
所有帧的 ray 必须按 coordinate time 汇总,沿时间从新到旧,通过可装入内存的 metric time slab 推进。不要按 frame 各自重复加载所需的 4D 数据。
每个 refinement pass 只追踪新请求的 samples:完整追踪后才能判断 image-plane triangle 是否需要细分,而早期 slab 此时已释放。不能在同一次 slab sweep 中临时创建新 ray 并回到相机时间重新追踪。
Ray 与并行
- 以 coordinate time
t作为 geodesic ODE 自变量,使 ray 演化与 slab 边界自然对齐。 - 批量 ray 状态采用 SoA
RayPool,避免 per-ray allocation;支持 activation、终止和 stream compaction。 - 用 OpenMP 对 active ray pool 做粗粒度循环并行。不要为单条 ray 或 triangle 创建 task,也不要引入细粒度 mutex。
- metric evaluator 的可变缓存和插值 scratch space 必须是 thread-local,不能共享可变 cache。
- 优先 bulk arrays、顺序 metric I/O、time-slab streaming 和 coarse-grained parallelism。
镜头映射与点源渲染
每帧在 image plane 上使用 adaptive triangle mesh。每个顶点保存 film 坐标、ray 状态、逃逸方向 n_inf 与频移信息。根据真实 mapping 与局部插值的误差、orientation consistency 和 Jacobian 奇异性进行局部细分。
最终从局部可逆 triangle 构造 inverse lens map:sky direction -> image position。同一恒星被多个局部 patch 覆盖时自然形成多像;不要依赖全局“第几阶像”分类。
catalog 内部数据保留 (direction, temperature, amplitude),而非 RGB。对每个像计算局部 magnification 与频率比 g,用 T_obs = g * T_emit 处理黑体频移,并以保留亚像素位置的 PSF 直接 splat 到 HDR framebuffer。
Backend 与模块边界
顶层 movie scheduler 不得依赖具体 metric 来源。时空 backend 至少应可替换为:Minkowski、解析 Schwarzschild,以及 nmesh 4D 数值时空;未来可加入 Kerr/BBH。
observer:worldline/tetrad 读取、插值和正交化;不实现 geodesic 或渲染。movie/frame:帧时间表、adaptive mesh、refinement 请求与 ray 结果回填。ray:批量 ray 状态、初始化、生命周期和 compaction。geodesic:3+1 null geodesic RHS、频移、ODE stepper 和 slab 内推进;不处理磁盘 I/O 或 frame mesh。spacetime:backend 统一接口、slab、metric/导数插值以及 capture/infinity classification。nmesh_backend:读取原生 DG node 输出、AMR lookup、Lagrange 空间插值及导数、时间插值和 puncture trajectories。catalog:Gaia/2MASS 等 catalog 的读取、内部转换和天球索引。optics/psf:黑体频移、linear RGB、flux、PSF 和 HDR 累积。output:HDR、曝光、tone mapping、PNG/EXR 与视频编码接口。
对 nmesh 数据,直接在原生 DG nodes 上用 Lagrange basis 插值及求空间导数;不要先重采样到 Cartesian uniform grid,也不要求相邻时间 slice 的 AMR tree 拓扑对应。对固定全局点,应分别在各 slice 的空间 mesh 上求值,再进行时间插值。
优先从 3+1 identities、已知 gauge RHS 或 temporal interpolant 的解析导数获得时间导数;不要为已有插值量另行做低阶 finite difference,也不要在 geodesic RHS 中计算不会使用的量。
黑洞终止
对 moving-puncture 数据,生产渲染使用经 AH calibration 得到、保守地位于 apparent horizon 内部的 puncture-centered cutoff 判定捕获。不要假定每次生产演化都会运行昂贵的 AH finder。可在未来加入 common-horizon 终止优化,但不得改变物理分类。
开发与验证顺序
按以下层级实现和回归验证,后续阶段不得绕过前一阶段的基准:
- Minkowski + 星表:验证 observer/camera projection、天球方向、catalog、温度/振幅、PSF 和 mesh。
- 解析 Schwarzschild:验证 capture、Einstein ring、多像、refinement、局部 inverse map、放大率和频移。
- 数值单 Schwarzschild:验证动态 4D slab streaming,并与解析解比较逃逸方向、频移和捕获分类。
- FOZ4c BBH:在上层架构不重设计的前提下接入成熟的 BBH 演化。
新增物理、插值或优化时,优先添加能与前一阶段比较的收敛测试或 regression test。尚未由 prototype/convergence test 决定的参数(如时间输出 cadence、时间插值阶数、slab 大小、refinement 阈值、PSF、ODE stepper)不要伪装成既定事实。
修改原则
- 改动应保持 backend、observer、geodesic、movie mesh 与 optics 的职责分离。
- 性能优化不得破坏 time-dependent tracing、局部可逆映射或点源的亚像素 PSF 渲染。
- 新增缓存先明确 ownership、生命周期和线程归属;高开销可变缓存默认 thread-local。
- 未在设计文档中明确的物理或数值取舍,应通过小型 prototype、基准或收敛实验确定,并同步更新设计文档。