ChenTW

记录理解世界的方法

·

4 次阅读

24 小时,我开发了一个动态演示晨昏线的 3D 地球教具

最近刷抖音,刷到一个地球晨昏线的动态视频:冬至、夏至的晨昏线扫过我国境内的 3D 动画。看完挺震撼 —— 它清清楚楚展示了为什么夏至时东北凌晨三点就天亮,冬至时天黑得又那么早,还有西部地区的时差感是怎么回事。这个视频是个很好的教具,但模型很简陋:一个转着的地球、一条线,细节全靠字幕撑。

恰巧我知道,豆包工作任务有点开发能力。于是就想:要不自己手搓一个?做一个更像 Google Earth 的工具 —— 输入一个日期,拖动当天的时间,就能看到那天的晨昏线压在哪个位置、昼夜怎么分布。

本地版:几个小时

本地版其实很顺利。从检索 GitHub 开始:现成的 3D 地球不少,晨昏线演示也有,但 “日期滑块 + 中国省界 + 省会标注” 凑成一个完整工具的,一个都没有。那就 three.js 自研,全部素材本地化,做到双击文件就能跑。

几个小时内,第一版就跑通了:一个会转的地球,一条跟着太阳走的线。那一刻很有成就感 —— 但也只是所有麻烦的开始。

在线版:DSH + DeepSeek 接管,外加一个惊喜

本地版做好之后,我想把它发布到个人网站上,做一个在线版。这一步交给了 DSH + DeepSeek 接管:审计出几个优化事项,逐条修完。

意外的惊喜在这里:cPanel 的 API 技能被我打通了。从那以后,AI agent 往 cPanel 服务器上发布东西就方便多了 —— 传文件、校验哈希、回滚,一条命令搞定,再也不用人工拖 ZIP 上传。这次发布「昼夜地球」是第一次实战,后来就成了固定套路。

中间还有几场仗

回到内容本身,几场硬仗一个都没少:

地图左右是反的。 第一个版本打开,中国是镜像的 —— 西在右、东在左,乌鲁木齐跑到了右边。查到底发现是 three.js 球体贴图方向的老坑:UV 排布和经纬度定义天生相反,光翻转纹理治标不治本。最终修法是两处配套、缺一不可:坐标转换时 x 取负,加上纹理平移半幅。修完乌鲁木齐终于回到左边。教训:看起来是 “转一下” 的事,往往是 “转两处” 的事。

地图版本也有雷。 早期原型用过国外开源的 Natural Earth 世界国界数据,后来审计时发现:国外开源地图的部分区域边界画法和我国主张不一致,直接用在面向公众的页面上是有风险的。幸好发现得早,立刻更换 —— 中国省界数据改用国内权威来源(阿里云 DataV),省界数据本身含完整中国轮廓,干脆不再绘制世界国界,从源头消除不合规隐患。现在页面所有地图数据都来自国内权威开源来源。

晨昏线是准的,光却是歪的。 晨昏线的数学很简单:知道太阳赤纬,算出日落角,画一个圆。但地球一转视角,晨昏线和光影边缘就错位,像两张图硬贴。查了一晚上,根因只有一句话:着色器里法线算在 “视图空间”,太阳方向却算在 “世界空间”。默认视角两者恰好重合,手一拖立刻露馅。统一坐标系,一行代码级别的修复。bug 往往不是复杂,是藏得深。

省会名字在闪。 名字转着转着穿到地球背面去了(标签不参与深度测试),视角一动还互相抢占位置。修法分三层:转背面自动隐藏、显隐改成透明度过渡、防重叠改成 “稳定优先”。顺带还跟 “字号该近大远小还是远大近小” 缠斗了两版。

手机一打开,地球黑了。 尤其 iOS 微信内置浏览器:纹理丢失、卡片堆叠、星空背景消失。改着色器绕开内存压力、图例改顶部横滑、星空改程序化生成,1.5MB 纹理改成按需加载 —— 先出画面,边界和纹理随后到。还有个最隐蔽的 bug:「按日期」播放时日期纹丝不动,本地测试 “通过”、真机不动 —— 原因是日期推进用的是 “速度 × 帧间隔”,60 帧的真机上一天的量加不到 1,永远进不了位;测试环境帧率低反而刚好跨过阈值,假通过。改成累积小数天数才治好。

最后的坑:豆包又掉链子了

到了收尾的 UI 最终优化阶段,豆包又犯了老毛病 —— 自然语言和截图识别的来回沟通,多次失败,开始摆烂。没办法,又回到 DSH + DeepSeek 审计优化,逐条对齐,最终才把界面细节收拾利索。

24 小时

总的来说,24 小时之内,这个教具干出来了。

最终的样子:日期和时间可以拖、可以选,四个节气一键跳转;右下角可以选城市(34 个省会),实时给出经纬度、太阳高度、日出日落和昼长;屏幕中间还有一个黑底红字的北京时间悬浮框,可以拖着走,不挡地球。数据来自 Natural Earth、DataV 和 three.js 官方素材,纯静态上线,挂在个人网站的子目录里,手机电脑都能打开 —— 就不放具体地址了,服务器扛不住太多人。

但那个抖音视频教会我的东西,现在别人也能亲手拖一拖了。

夏至日晨昏线完整扫过中国全境:24 小时动画