45.8 MB 的 factory_machine.glb 压到 3.2 MB,省 93%,14.3 倍,耗时不到 1 秒------这是 Zipoly 官网给的示例,默认压缩级别 7。
看到这个数先别激动,大屏项目里它只是一半的答案。下面是我处理一个园区大屏时的顺序、配置和踩的坑。
环境
- 交付目标:Web 大屏,Three.js + GLTFLoader,Chrome / Edge
- 源模型:厂区 FBX + 设备 OBJ + 4K PNG 贴图,合计 3 个多 G
- 工具:3D 模型压缩工具 Zipoly 桌面版(Windows),离线跑,不联网
处理顺序
- 统一格式:混着 FBX / OBJ / DAE 时先转成 GLB,Zipoly 支持 GLB / glTF / FBX / OBJ / STL / DAE / PLY 七种互转
- 看体检:导入后自动扫,重复顶点、超大纹理会列出来
- 定引擎:Draco 还是 Meshopt
- 压贴图:转 KTX2,最大边长按实际视距定
- 压完用内置查看器转一圈,看有没有变形
- 还卡,再回去减面 + LOD + 按需加载
引擎和手段怎么选
| 维度 | Draco | Meshopt | 减面 / LOD |
|---|---|---|---|
| 解决什么 | 文件体积(几何) | 文件体积 + 顶点缓存 | 每帧要处理的面数 |
| 压缩率 | 最高约 90% | 比 Draco 更高 | 不压体积,只降面数 |
| 兼容性 | Three.js / Babylon.js / model-viewer 原生支持 | 需解码器支持,不可用时自动降级 Draco | 引擎层实现 |
| 参数 | 1--10 级 + 位置 / 法线 / UV 量化精度 | 默认配置即可 | 按视距定阈值 |
| 什么时候用 | 大屏要兼容多浏览器,默认选它 | 纯几何大件、想再小一点 | 加载完掉帧时才动 |
结论:先跑一遍 Draco 看体积,掉帧再动减面和 LOD,顺序反了会白做一轮。
Three.js 侧怎么接
js
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
const draco = new DRACOLoader();
draco.setDecoderPath('/draco/'); // decoder 是静态资源,别忘了随包发
const ktx2 = new KTX2Loader()
.setTranscoderPath('/basis/')
.detectSupport(renderer);
const loader = new GLTFLoader();
loader.setDRACOLoader(draco);
loader.setKTX2Loader(ktx2);
loader.load('/models/factory.glb', (gltf) => {
scene.add(gltf.scene);
});
结果
- 几何:Draco 默认 7 级,官方示例 45.8 MB → 3.2 MB(−93%)
- 贴图:转 KTX2,纹理体积再砍九成,显存占用也降
- 我们那个场景压完只剩原来的零头,首屏从二十几秒掉到几秒
坑
- 别指望二次压缩:已经压过的模型再压几乎不动,纯浪费时间
- 免费版单文件 20 MB(纹理 5 MB),一次一个;授权后 500 MB 并开放批量,大屏单件设备模型很容易顶到这个限制
- Draco 只减体积不减面数:压完 3 MB 但有 200 万面,帧率不会变,还是得减面 + LOD
- decoder / transcoder 是静态资源,忘了随包发,线上直接加载失败
- LOD 和按需加载是引擎层的活,桌面工具不接管,别指望拖进去点两下就全好