把银河调对:一个晚上,从"星星为什么隐藏"到太阳系真的转起来
——/galaxy/ 模块 2026-11-09 夜间迭代全记录
写在前面
这个模块是一个运行在浏览器里的银河系三维认知版图:200 万颗星沙积分成的盘、5 万颗真实轨道小行星、2 万颗 Gaia 近域恒星、24 颗距离最近的真实著名恒星、JPL Horizons 每日更新的行星轨道,以及星座、伴星系、暗物质晕等标注层。本文记录 2026 年 11 月 9 日晚间的一轮密集迭代——起点只是用户的一句话:"靠近群星时,星星会隐藏",终点是太阳系在银盘上真实地绕银心运行。全部改动集中在 app/templates/galaxy.html 一个文件内。
一、体验线:七轮"看起来更对"的打磨
1.1 星星不许隐藏
最初的抱怨:推进到恒星附近时星星会淡出消失。排查发现两层刻意的"淡出":近邻星有单星穿越淡出(相机进入 0.004 kpc 内透明度衰减到零),还有整层淡出(进入太阳系 0.3 kpc 后 24 颗近邻星整体消失)。全部去掉,任何距离常显 0.95 全清晰。
1.2 放大更亮、穿星划过
用户要"漫天恒星划过"的效果。这需要星点在贴近时被钳制在一个像素上限内、同时保持明亮。我们把所有星层的贴近上限统一到 48px(后按反馈回调到 28px),透明度衰减从平方曲线改成线性、最终彻底取消——现在的规则是"永不衰减,放大增亮":星点从 2.5px 起随尺寸渐增透明度,峰值钳 0.85(防止加色饱和糊成球)。
1.3 近域恒星距离自适应亮度
2 万颗 Gaia 星在银河全貌时会叠加成过亮的团。给这层加了独立的 uGain uniform,按相机到太阳的距离做对数插值:靠近太阳系(<1 kpc)增益 1.0,银河全貌(>2 kpc)增益 0.05。
这里有一个值得记录的物理认知:最初只压到 0.5,用户反馈"远的亮、近的暗,感觉反了"。代码方向从来没反——是加色叠加的几何效应:远景时 2 万颗星挤在几十像素里,每颗 0.3 的增益叠加约 28 层/像素照样饱和发白;近景星点铺满全屏,总量反而小。远景增益必须压到 0.05 量级才能把叠加总量拉回不饱和区。
1.4 柔光晕换成硬沙粒
用户连续三轮投诉"模糊":柔光晕贴图(64px、光晕拖到 65% 半径)被放大钳制后是满屏棉花球。最终方案是"硬沙粒"纹理——128px、10% 半径内全亮实心核、28% 完全截止——所有点状星层统一使用。紧实的近邻星亮斑(NEIGHBOR_GLOW_TEX)替换了原来 35% 半径的宽晕。
1.5 远景银河消失之谜
换硬贴图后拉远,银河盘没了——只剩核球和星云。这是当晚最漂亮的 bug:点精灵的片元中心永远落在贴图半径约 0.7 的位置,硬贴图在 28% 处截止,1-2px 的星点采样到的全是透明区,能量直接归零。旧柔光晕之所以远景正常,纯属巧合——它的光晕拖得够远,恰好盖住了采样点。
修复两步:STAR_TEX 关闭 mipmap(中等尺寸星点直采样实心核,不被全图平均摊薄);片元着色器对 ≤2.5px 的小点特判——绕过贴图画实心圆点,透明度按旧柔光晕的全图平均亮度 0.147(后提亮至 0.20)折算。数值上对 1px 和 2px 星点都是能量无损的。
1.6 太阳亮度的五连调
用户先问"太阳亮度是否符合实际"——答案是不:真实太阳从银河外部看视星等约 +22(绝对星等 +4.83 的 G2V 普通恒星),肉眼不可见;而渲染里它是一个 1-2° 的炽白导航信标。之后按反馈迭代了五版:辉光上限 0.65→0.06;加视角下限 0.012→0.008→0.002 rad;加过强衰减 farDim、又按"保持这个亮度"和"调到最暗"来回调整两次。最终状态:0.5 kpc 内全亮,8.3 kpc 处亮度约 1/25,银河全景只剩一个几像素的微弱可寻小点——比真实亮得多(那是导航需要),但量级始终是"一颗星"而不是"一盏灯"。
1.7 彩色碎斑球之谜
用户截图问"太阳周围蓝色球和粉红球是什么、太大太模糊"。答案是 24 颗近邻真实恒星——粉红/红是 M 型红矮星、橙是 K 型、蓝白是 A/F/G 型,颜色全部按真实光谱型取值;球里的"彩色碎点"是加色混合精灵不遮挡背景,身后 2 万颗 Gaia 星直接"透"过光球。巨大的根源:旧代码给它们设了 0.35 弧度(20°)的视角上限。收到 0.012 rad(约 0.7°)后,任何距离下它们都是"亮星 + 小光晕"的合理形态。
二、修掉的隐藏 bug
Gaia 近域恒星层和小行星带层从来没有显示过。 着色器声明了 aMaxPx 属性,但这两层手工建几何时漏传;WebGL 里缺失的属性读出 0,gl_PointSize = clamp(px, 1.0, 0) 且透明度恒为 0——两层隐形了几个版本没人发现。补传属性后,太阳近域凭空多出 2 万颗真实星点。
太阳标签绕银心打转(旧账):标签走 galaxy.localToWorld,随星系自转绕银河中心转圈、脱离太阳。本轮改成动态标签,实时跟随运动中的太阳。
三、科学线:让人类已知的知识长进去
视觉满意之后,用户要求"从人类已知评价模型",并按评估结论把五条科学性改进全部落实。
3.1 较差自转(最重要的物理修正)
此前整个银河是刚体自转——这是星系动力学的大忌:刚体转几圈旋臂就被剪切消失,而较差自转(内侧快、外侧慢)正是旋涡结构得以存在的根本机制。修正分两层:
- 星系组整体以太阳轨道角速度
OMEGA_SUN = 0.04 rad/s转动(这是"图案速度"的示意值); - 盘/核球/银晕的 200 万+5 万星点在顶点着色器里按平坦旋转曲线叠加差值角:
ω(R) = Ω·8.3/√(R²+2.5²)——太阳处与图案共转,内侧超前、外侧滞后,核球近似刚体。
3.2 恒星类型占比按真实 IMF
盘星配色概率从"M 型占 12%"改为符合初始质量函数的真实比例:M 型红矮星约 66%(宇宙中最常见的恒星)、G/K 类约 28%、年轻蓝星约 4%(旋臂内过密度提升到 12%)。
3.3 本星系群伴星系数据层
新增三个真实位置的伴星系(RA/Dec/距离均为实测值,星点云用高斯扁平椭球近似光度轮廓):
| 成员 | 距离 | 说明 |
|---|---|---|
| 大麦哲伦云 LMC | 16.2 万光年 | 300 星 + 光晕,恒星形成活跃偏蓝白 |
| 小麦哲伦云 SMC | 20.1 万光年 | 220 星 + 光晕 |
| 人马矮星系 Sgr dSph | 8.4 万光年 | 150 星,标注"正在撞入银盘,已形成星流" |
它们在场景空间不随银河较差自转(本星系群近似惯性系),标签走世界坐标。
3.4 标签措辞去误导
"真实 AU 比例"改为"轨道间距为真实 AU 比例 · 行星尺寸示意放大"——原措辞掩盖了两个物理事实:行星半径相对轨道放大约 700 倍;整个太阳系相对银河尺度放大约 5×10⁸ 倍(真实 AU 在屏幕上次像素)。共修正 4 处(面板标题、场景标签、代码注释)。
3.5 太阳系真的转起来了
用户问出关键一句:"太阳系是没动的吗?"此前用共转参考系辩护过,但用户选择了字面运动。实现后发现整个相机导航模型(focusOf 重力井)本来就是"拉近即收敛到太阳坐标"的结构,只需把它从写死的 (SUN_R, 0.03, 0) 改成实时 sun.position——缩放、拖拽、点选、空域行走、行星选中跟随就全部自动正确,无需相机随动 hack。
太阳锚定世界整体改为"日心相对坐标 + 组锚定":Gaia 2 万星与 6D 速度箭头、星座天球、系外行星宿主星、装饰小行星带、24 颗近邻星、点光源、行星轨道圈全部跟随;行星、月球、SBDB 小行星带、人造卫星本就逐帧以 sun.position 起算,自动正确。现在银河全貌下能看到太阳带着整个太阳系沿 8.3 kpc 轨道绕银心运行(示意周期 2.6 分钟),任何时候拉近,导航都稳稳落在太阳系上。
四、插曲:白屏事件与真相
晚间一次"网页卡住 + 白屏"的排查:服务器侧逐项验证全部健康(页面、7 个 API、全部静态资源毫秒级 200,无外部 CDN 依赖),真凶在客户端——Safari 的 WebKit GPU 进程崩溃重启(内存 444MB→135MB),银河页签 WebContent 冲到 1GB/22% CPU 后被内存看门狗杀死。诱因之一是排查过程中在用户的机器上跑了无头 Chrome 软件渲染实例(机器负载冲到 5-11)。教训:在用户机器上做重型诊断前,先确认不会和用户的实际工作争抢资源;页面自身的防御(像素比上限 1.5、性能看门狗、?nolocal=1 与 /galaxy/classic/ 轻量版退路)依然有效。
五、最终状态与已知妥协
模型现在分三层诚实对外:数据层(行星轨道、小行星、卫星、近邻星、Gaia 星、伴星系、星座方向)是真实观测值;结构层(星沙盘、旋臂、尘埃、光晕)是参数化示意,但运动学遵循较差自转、恒星统计遵循 IMF;尺度层明确标注了压缩比例。已知妥协:亮度为观感调定不代表流量;时间尺度跨层不同(行星 30 秒=1 年,银河年 2.6 分钟,均为示意);太阳系与银河的 5×10⁸ 倍比例压缩使恒星物理上"在太阳系内部",这是可视化的必要代价。
附:当晚关键数值速查
| 项目 | 旧值 | 现值 |
|---|---|---|
| 近邻星视角上限 | 0.35 rad(20° 巨球) | 0.012 rad(0.7° 星点) |
| Gaia 贴近上限 | 10px(且整层隐形) | 28px |
| 星点透明度 | 平方衰减 → 线性 → 无衰减 | 放大增亮至 1.8 倍,峰值钳 0.85 |
| 小点能量折算(远景) | —(mip 平均丢失) | 0.20,≤2.5px 特判实心点 |
| Gaia 距离增益 | 无 | 1.0(<1 kpc)→ 0.05(>2 kpc) |
| 银河盘透明度 | 0.22 | 0.26 |
| M 矮星占比 | 12% | 66% |
| 太阳亮度 | 0.65 上限全亮信标 | 远景 1/25,近景全亮 |
| 银河自转 | 刚体 0.05 rad/s | 较差 ω(R),共转 Ω=0.04 rad/s |
| 太阳系位置 | 固定 (8.3, 0.03, 0) | 沿轨道实时运动 |