难度:★★★(选修课;建议先学完第 13、14、19 课)
教材:开源项目 RhineLabUI(https://github.com/LBEILC/RhineLabUI,在线体验https://rhine.lubeiluchen.cc/)
预计时间:讲解 90 分钟 + 练习 60 分钟(可分两次上)
学完你能:看懂一个成熟 Three.js 项目的组织方式,并拿到 6 个可迁移的工程模式
不允许搬运素材(第 4 步有专门的边界练习)
AI 写出来的大项目,靠什么保证质量?(答案在本课第 6 个模式)
你已经学习了一个 Three.js 项目(「天使与恶魔」的森林绘本舞台,第 13 课讲过)。
这个案例和它是同一技术栈,但成熟度更高。对照学习最有效:
| worry 前端 | RhineLabUI | |
|---|---|---|
| 构建 | Vite + TS | Vite + TS(v7) |
| 3D | Three.js 森林舞台 | Three.js 档案阵列 |
| 演出编排 | show/director.ts(流式→节拍) | boot-motion.ts + 场景时间轴(逐帧对齐原片) |
| 内容 | 提示词生成 | content/archives.json 单一数据源 |
| 交付 | 后端托管静态产物 | PWA 离线 + 壁纸版独立仓库 |
| 验证 | Puppeteer 验收脚本 | 8 个 check-*.mjs + 对照工具 + 验证文档 |
git clone https://github.com/LBEILC/RhineLabUI.git
cd RhineLabUI
npm ci # 需要 Node 22.12+(用 Node 24 也行)
npm run dev # 打开 http://127.0.0.1:5173/
登录后打开 F12,带着下面这份清单玩(每一项都能对应后面的技术点):
「拆解档案」六组展开、「一键重组」
/?scene=archive、/?scene=detail、/?time=28&freeze=1官方 README 的工程结构表已经写得很清楚,我整理成一张"模块地图":
RhineLabUI/
├── src/
│ ├── main.ts 页面状态、阅读、检索、收藏、快捷键(总入口)
│ ├── boot.ts / boot-motion.ts 开场界面 + 逐帧时间轴(DOM/SVG 驱动)
│ ├── scene.ts / archive-loop.ts Three.js 场景 + 循环阵列 + 抽取/归位
│ ├── model-viewer.ts 独立 360° 查看器 + 拆解/重组动画
│ ├── decryption.ts / document-decryption.ts 模型解密轨迹 + 正文同步
│ ├── audio.ts 交互音效 + 三轨配乐
│ ├── render-quality.ts / quality-renderer.ts 画质预设与渲染管线
│ ├── data.ts / brand.ts 数据映射 / 品牌图形(SVG 路径共享)
│ └── ui-transitions.ts 弹窗与页签过渡
├── content/archives.json 五类 40 份档案(页面与下载共用)
├── public/assets/*.glb 运行用的三维模型(含六组拆解信息)
├── art/ Blender 源工程 + 建模脚本(MCP 可执行)
├── scripts/ 导出、检查(check-*.mjs)、打包(PWA/壁纸/部署)
├── reference/ 对照工具页(原片 vs 复刻逐帧比对)
├── verification/ 分阶段验证记录(改动的证据)
└── DESIGN.md 视觉与行为基准(决策日志)
和作者的 worry 对照: main.ts / stage / show/director / audio / ui
几乎能一一对应——说明分层方向是相同的,只是它每个模块都做得更深。
它怎么做:五类档案、每类八份,共 40 份内容,但要看起来"永远翻不完"。
做法是把内容编号与物理位置解耦:内容按周期映射到行列坐标;
交互时维护 9 列 × 32 行共 288 个位置,按镜头附近的"可见窗口"循环补位。
还有一个细节非常专业:逻辑坐标超过 2048 时整体平移坐标与运动状态,
保持世界位置/速度/波纹相位连续——这是为了防止长时间运行后浮点精度下降。
你能学到:①"有限内容做无限体验"的映射思路 ②浮点数不是无限的,
位置量大了要主动归零重排(游戏开发常见技巧)。
教材项目里:worry 的 director 用队列缓冲"生成快 vs 播放慢";
和"循环补位"是同一类"生产/消费协调"问题,只是维度不同。
它怎么做:开场不是 Three.js 做的,而是 DOM/SVG(boot.ts + boot-motion.ts):
逐字输入、圆环旋转、logo 连续描边、身份验证文字,全部对齐原片的帧点,
用"连续插值 + 离散闪切"还原 25fps 的节奏。
关键取舍:不依赖 CSS 动画的播放进度,所以慢放、暂停、前后跳帧都能保持画面状态一致。
你能学到:①能用 2D 做清楚的,不一定上 3D(DOM/SVG 更轻、更清晰)
②"时间轴驱动"和"CSS 动画"的区别——前者可被程序控制、可跳帧。
教材项目里:教材项目里 portfolio 的笔顺动画(ink.js)就是 SVG 描边 + 延迟编排;
这个案例相当于它的"专业加强版"(帧点级控制 + 调试工具)。
它怎么做(model-viewer.ts):
「拆解档案」把紧固件、盖板、环组、光学核心、信息基板、背板、框架六组部件
沿厚度轴分离;「一键重组」准确归位;中途反向操作保留当前运动位置与速度。
更值得学的是状态保持:切换"清晰/磨砂"玻璃,不重置当前视角和拆解进度;
旋转屏幕只调布局,不复位视角。
你能学到:交互系统的核心不是"能点",而是"点完之后状态还是对的"。
教材项目里:worry 的"打断 + 快照回滚"(第 14 课)就是流式场景下的状态管理;
这里则演示了 3D 交互场景下的同一课题。
它怎么做:所有档案内容在 content/archives.json(一份 JSON 管页面和下载)。npm run dev / npm run build 之前会自动跑 scripts/export-records.mjs
生成下载文本;npm run check:content 校验数据规则与导出一致性。
你能学到:内容改一处、处处生效;数据进构建管线前先校验。
教材项目里:course-publisher 的 course.yaml + build.py、portfolio-site 的 portfolio.json + 契约测试——同一个思想;
这个案例可以看它"自动化到 predev/prebuild 钩子"的程度。
DESIGN.md 里全是教科书级的排障记录,挑两个:
给该材质单独加 polygonOffset(factor=-1, units=-2) 解决(z-fighting)
near=0.1 导致深度缓冲精度不足;near 改为 5、far 保持 300 后,理论步长从 0.003089 降到 0.00006077——
近裁剪面不是"越小越好",它会影响深度精度
你能学到:渲染问题要能换算成数字去解释和修复;
以及"把为什么改、改了之后误差多少"写进文档。
教材项目里:教材项目里做过"帧率不够自动降画质"(render-budget.ts)——
这个案例把它升级成了四档预设 + 九项细调 + "超级性能模式"。
check-motion / loop / appearance / assembly / decryption / shell / internal-optics / quality——跑一遍就能发现"动效/循环位置/装配结构/解密轨迹"的回归
reference/ 里是和原片逐帧比对的页面(并排、放大、慢放、单步)verification/ 每份文档记录"改了什么、怎么证的、局限在哪"(比如"实时折射与逐像素差分认证还有差距"——主动承认局限)
壁纸版拆成独立仓库并发布到 Steam 创意工坊
AI 写得多快,验证就得有多严
你能学到:专业项目的差距不在"写得多",而在"改得动、证得起"。
教材项目里:教材项目的 verify.mjs(CDP 浏览器验收)、contracts.test.mjs、tests/ 就是这套文化的雏形;可以照着补齐"对照工具"这一环。
为什么这步单独讲?因为它是大部分复刻类项目会踩的坑,也是成人世界的规则。
这个项目做得非常规范,它的 LICENSE 分成两层:
| 内容 | 授权 |
|---|---|
| 程序代码、建模脚本、技术文档、Blender 工程、GLB 模型、原创配乐、截图动图 | MIT(可用、可改、可商用,保留版权声明) |
| 《明日方舟》名称/标志/设定/原 PV/原作视觉/原片音频采样 | 不在授权范围,权利归各自权利人 |
| MiSans 字体、Novecento 字体、Rolling Number 等第三方 | 各自许可证,不因本项目而改变 |
你要学的:技术上完全可以学;但做自己的作品时——
对照教材项目: portfolio 给封面标注"设计示意·非实机截图"、
查资料给未验证来源打 ⚠——这就是同一件事:诚实标注边界。
技术练习
/?scene=archive 直接进阵列、/?time=28&freeze=1固定在时间轴某刻。说说看"固定时刻"对调试动效为什么有用
content/archives.json 里加一份档案,跑npm run check:content 和 npm run export:archives,看自动校验和导出
reference/decryption-review.html,理解"对照页"怎么帮人逐帧校准(这是你最该学的一件"工具")
DESIGN.md 找一条"数值调整"记录,然后给你的 worry 写一条设计记录(一个数值 + 为什么 + 验证方式)
(低/中/高 + 自动降档),参考它 render-quality.ts 的思路先写方案,不用全做完
JS 的浮点数精度;世界坐标很大时微小位移会算不动
用 three.js 加载显示——走通"建模 → 导出 → 加载"的最小链路
边界练习
①哪三类东西可以直接用(附条件)②哪两类东西绝对不能搬
数值化排障、交付验证文化
对照工具(和参考逐帧比)、验证记录(改动的证据)、决策日志(为什么这么改)
| 术语 | 人话解释 |
|---|---|
| GLB | 打包好的 3D 模型文件格式(Three.js 常用) |
| 时间轴驱动 | 用程序按时间点控制画面,而不是纯 CSS 动画 |
| 浮点精度 | 计算机里小数不是无限精确的,数值大了误差会变大 |
| z-fighting | 两个面几乎重叠时,渲染出现闪烁条纹 |
| near / far 裁剪面 | 相机能看到的最近/最远范围,影响深度精度 |
| PMREM | Three.js 生成环境反射贴图的技术 |
| PWA | 可安装、可离线的网页应用 |
| 回归检查 | 确保新改动没把旧功能弄坏的自动检查 |
| MIT 许可 | 很宽松的开源协议:可用可改可商用,保留声明 |
art/ 里的 Blender 脚本 + 你自己的建模经验,可以走"Blender 建模 → GLB → Three.js 展示"的完整链路
src/scene.ts 对照着读案例项目致谢:LBEILC / RhineLabUI(MIT)。本课仅用于技术学习与方法分析。