4.6 引擎选型与资源加载对照 本节摘要:Three.js 提供场景图与庞大的示例材质,上手快,自定义管线要钻 RawShader 与钩子。Babylon.js 更像完整运行时,加载、工具、物理、GUI 捆得紧。PixiJS 一类走 2D 批处理,不适合当 3D 查看器。裸 WebGL 加独立 glTF 解析器,控制权最大,加载与压缩回退要自己扛。选型按管线是否产品、团队会不会读状态机、资源是 glTF 还是自研格式来,而不是按星数。
本节摘要:Three.js 提供场景图与庞大的示例材质,上手快,自定义管线要钻 RawShader 与钩子。Babylon.js 更像完整运行时,加载、工具、物理、GUI 捆得紧。PixiJS 一类走 2D 批处理,不适合当 3D 查看器。裸 WebGL 加独立 glTF 解析器,控制权最大,加载与压缩回退要自己扛。选型按管线是否产品、团队会不会读状态机、资源是 glTF 还是自研格式来,而不是按星数。
阅读完本节,你应当能够:
引擎自带加载器,是因为场景图需要网格、材质、贴图槽一次填好。裸 API 的加载器应停在“解析出缓冲与材质参数”,不要偷偷建灯光系统。把 Babylon 的加载当 Three 的加载用,会拖进额外运行时。把 glTF 解析库当引擎用,会缺绘制循环。对照第 1.3 节:加载可拆。
资源管理是 CPU 侧缓存:同一 URI 的纹理只解码一次,GPU 对象只创建一次。引擎有 Cache;裸写要 Map。单页应用切路由必须 dispose,否则显存只涨。这与用哪家引擎无关,与是否忘记删除 GPU 对象有关。
应用 → 加载器解析 → 几何与材质描述 → 上传缓冲纹理 → 进入绘制 引擎把后三段包在一起 裸写可以只买第一段
| 方案 | 擅长 | 代价 | 典型 |
|---|---|---|---|
| Three.js | 场景图、生态例子、自定义材质入口 | 抽象泄漏时要读源码 | Web 产品查看、创意站 |
| Babylon.js | 完整工具链、加载与场景序列化 | 体积与概念更重 | 重交互、要编辑器感 |
| Pixi / 2D 引擎 | 海量精灵合批 | 没有 3D 灯光合同 | 2D 游戏、HUD |
| 裸 + glTF 解析 | 管线可控 | 压缩回退、动画、切线要自己接 | 自研渲染器、教学进阶 |
| 现成查看器组件 | 最快上线 | 几乎不能改管线 | 营销活动 |
OBJ 只有几何与简陋材质色,UV 有了,PBR 槽没有,切线常要自己算。glTF 是运行时格式:缓冲、索引、材质金属粗糙、动画、场景节点一包。CPU 解析 glTF 比 OBJ 重,但少了很多自创约定。自研二进制可以更贴自己的渲染器,要自己写导出。没有一种格式“更 WebGL”,只有谁更接近你的 GPU 对象布局。
压缩:几何 Draco 类方案在 CPU 解压再上传;纹理 ASTC/ETC 在 GPU 原生。加载时间与显存的对照不同。引擎加载器通常有回退链:压缩失败用 PNG。裸写忘记回退,某品牌手机全黑。这是 4.5 节扩展矩阵在资产上的孪生问题。

解码 4K PNG 卡在首次展示,那是 CPU 与上传。运行后掉帧,不该再怪加载器,该进 4.7 节分端。有人把所有贴图预加载到开场,首屏 20 秒;有人全懒加载,相机一转卡一下。对照:首屏可见的低 mip 或小图先上,其余闲时解码。引擎有 mip 与进度回调;裸写自己排队列,注意上下文必须在拥有它的线程上传。
颜色空间:glTF 反照率 sRGB,线性工作流在引擎里有开关。开关与 canvas 输出、贴图解码不一致时,模型看起来灰或过饱和。这不是加载失败,是合同。法线花了查切线与镜像 UV。动画抽风查节点矩阵是列主序还是行主序、时间单位。加载器“成功”只保证对象创建,不保证外观合同。
⚠️ 常见坑:在引擎场景里又用裸 API 加载一张纹理绑到 TEXTURE0,引擎下一帧把单元改走。资源所有权必须单一。
💡 关键直觉:选引擎是选翻译器,选格式是选打包约定。翻译器解决不了错误的打包,打包也替代不了翻译器的合批策略。
PlayCanvas 一类带编辑器的方案,适合协作出场景,不适合塞进“我只要画一个缓冲”。工具向引擎会把资源放云端或编辑器格式,导出到运行时。团队若没有编辑器需求,不必为了加载 glTF 上完整云编辑器。需求减法再次有效。
教学可以。生产要付导出、切线、动画、材质版本的债。除非你的渲染器物体结构非常特殊,否则先接 glTF,特殊数据用 extras。自研格式的正当理由是极限包体或流式体素,不是嫌 glTF 字段多。
选型还有非技术对照。许可证是否允许你们的分发方式;包体 gzip 后多少;是否强制 WebGL2;社区问题的回答速度。技术博客爱评 API 美感,项目经理关心包体与招聘。招聘市场上会 Three 的人多于会裸 WebGL 的人。若产品是查看器,招人成本也是封装轴的一部分。自研渲染器要按“招得到维护者”来评估,不是按周末激情。
加载队列:相机对着的模型与第一张反照率最高优先;环境立方体次之;ORM 与法线再次;音频与无关关卡最低。CPU 解码有并发上限,太多 Image 同时 decode 会挤主线程。限流 2 到 4 路。引擎加载器有 priority;裸写自己排队。失败重试要有次数,避免坏 URL 打满队列。坏 URL 是运维问题,渲染器应显示占位而不是死循环。
内存预算写成数字:纹理 128MB、几何 32MB。超了就降 mip 或卸远距物体。移动 Safari 杀页很凶。引擎 dispose 必须接到路由离开。单页应用最容易漏。漏了之后表现为滑一会儿卡,像 GPU 瓶颈,其实是 CPU GC 与显存压力。4.7 的分端在这里也适用:先看内存曲线,再看帧时间。
glTF extras 可带你们自己的阴影是否投射标记。加载器把标记变成 CPU 列表,供 4.2 的投射者集合使用。格式不仅是网格,也是效果路线的序列化。自研字段写进文档,避免美术与程序各猜各的。
贴图更新后浏览器 HTTP 缓存会让用户看见旧 ORM。加载器要有版本参数或哈希文件名。这是 Web 缓存合同,不是 GL。引擎 loader 的 URL 必须带哈希。裸写同样。否则你会以为着色器坏了,其实采到上周的金属度。破坏缓存是加载器责任,列进发布清单。与 dispose 一样,属于资源生命周期,不是渲染公式。
颜色空间开关、缺 IBL、反照率当线性或相反。不是解析失败。解析失败通常没网格。有网格有 UV 仍灰,查 4.1 线性与 4.3 槽。加载器成功只保证对象在。
完整运行时加示例着色器加多余加载器。换查看器组件或树摇。包体是封装轴账单。活三天的页不该下完整编辑器运行时。gzip 后数字写进发布门禁。
没 dispose。纹理与几何仍被场景引用。路由钩子必须拆引用再 dispose。泄漏像 GPU 越用越慢。内存曲线比感觉可靠。引擎与裸写都会漏,谁创建谁删。
资源文件名带内容哈希。发布清单含包体门禁。加载器排队优先级写死。失败重试三次转占位。dispose 接路由。引擎与裸对象禁止共有同一张纹理。glTF extras 字段文档化。颜色空间开关进启动日志。包体超门禁不许发活动页。招聘与许可写进选型记录,避免一年后用爱发电维护自研核。选型记录与 1.3 的控制权账单是同一张纸的正反面。纸要留在仓库,不留在聊天记录。
选型记录存仓库:控制权、包体、许可、招聘、格式。一年后还能看见为什么没自研。加载器哈希与优先级写测试:改文件内容必须改 URL,否则缓存测试失败。dispose 接路由的测试用显存 API 或对象计数,离开后计数归零。不归零打回。灰模先切颜色空间再加 IBL。加灯救灰会把 4.1 的能量政策冲掉。2D 引擎禁止当 3D 查看器引进项目,即使它也能画三角。合批模型不同,后面阴影与蒙皮都会别扭。别扭的成本会超过当时省下的学习时间。学习时间是一次,别扭是每天。
生命周期测试离开路由后对象计数归零。不归零不发版。发版后的滑卡常是泄漏,不是新着色器。泄漏像 GPU 瓶颈,分端会看到内存涨、GC 尖刺。尖刺在 CPU。治泄漏用 dispose,不用减槽。减槽是 GPU 药。交叉吃药会把外观砍了,卡还在。记录让药对上病。
现场对照时只改一个变量。同时改版本、封装、通道,归因会消失。消失之后只能靠感觉,感觉正是本书要拆掉的东西。把改动写成一条,测完再写下一条。一条一条,四组对照才用得上。用不上的对照表只是装饰。装饰填不满格子,格子空着就不要标完工。加载这一格改完,离开路由计数归零,不要只看首屏出模。
下一节用案例把优化收束成两端账单:CPU 提交税对 GPU 填像素税。