Meshopt 压缩深度解析,为什么它比 Draco 更快

从原理到实战,搞懂 Meshopt 和 Draco 的本质区别


前言

做 Web3D 的同学应该都知道 Draco 压缩,它是 Google 开发的 3D 几何数据压缩算法,Three.js、Babylon.js、model-viewer 都支持。

但最近 Meshopt 越来越火,官方宣称解码速度比 Draco 快 5-10 倍。这到底是不是吹牛?今天从原理层面分析一下。


先说结论

对比项 Draco Meshopt
压缩率 高(70-90%) 更高(75-95%)
解码速度 快 5-10 倍
编码速度 快 3-5 倍
内存占用 中等
框架支持 广泛 Three.js r136+

结论:新项目优先用 Meshopt,老项目或需要兼容 model-viewer/Babylon.js 的用 Draco。


一、Draco 的原理

Draco 使用的是预测 + 熵编码的方式:

1.1 预测编码

对于网格中的每个顶点,Draco 会预测它的位置:

scss 复制代码
预测值 = f(相邻顶点)
残差 = 实际值 - 预测值

由于相邻顶点通常很接近,残差值会很小,存储残差比存储原始值更省空间。

1.2 熵编码

对残差值进行熵编码(类似 zip 压缩):

  • 出现频率高的值用短编码
  • 出现频率低的值用长编码

1.3 解码过程

解码时需要:

  1. 反向熵编码
  2. 重建预测
  3. 计算原始值

这个过程需要遍历整个网格拓扑,所以解码速度受限。


二、Meshopt 的原理

Meshopt(基于 gltfpack/meshoptimizer)采用的是量化 + 简单编码的方式:

2.1 量化

将浮点数转换为整数:

javascript 复制代码
// 原始值:0.123456789
// 量化为 16 位整数:8053(假设范围 [-1, 1])
quantized = Math.round((value - min) / (max - min) * 65535)

2.2 Delta 编码

存储相邻顶点的差值:

javascript 复制代码
// 顶点序列:[100, 102, 105, 103]
// Delta 编码:[100, 2, 3, -2]

2.3 简单变长编码

使用简单的变长整数编码(varint):

javascript 复制代码
// 小值用 1 字节,大值用更多字节
// 0-127: 1 字节
// 128-16383: 2 字节
// ...

2.4 解码过程

解码时只需要:

  1. 读取 varint
  2. 累加 delta
  3. 反量化

不需要遍历网格拓扑,所以解码速度极快。


三、为什么 Meshopt 更快

3.1 数据局部性

Meshopt 的数据是顺序存储的:

erlang 复制代码
顶点0.x, 顶点0.y, 顶点0.z
顶点1.x, 顶点1.y, 顶点1.z
顶点2.x, 顶点2.y, 顶点2.z
...

CPU 缓存友好,顺序读取效率高。

Draco 的数据是按拓扑存储的:

erlang 复制代码
面0的顶点、面1的顶点、面2的顶点...

需要随机访问,缓存命中率低。

3.2 算法复杂度

操作 Draco Meshopt
解码复杂度 O(n log n) O(n)
内存访问 随机 顺序
分支预测 难预测 易预测

3.3 实测数据

javascript 复制代码
// 测试代码
const decoder = new MeshoptDecoder()

console.time('Meshopt')
decoder.decodeVertexBuffer(target, vertexCount, vertexSize, source)
console.timeEnd('Meshopt')
// 约 2-5ms

const dracoLoader = new DRACOLoader()

console.time('Draco')
dracoLoader.decodeDracoFile(buffer)
console.timeEnd('Draco')
// 约 15-30ms

四、实际项目中的选择

4.1 选 Meshopt 的场景

  • Three.js 项目(r136+)
  • 追求极致加载性能
  • 移动端 Web
  • 需要快速解码的交互场景

4.2 选 Draco 的场景

  • 需要兼容 model-viewer
  • Babylon.js 项目
  • 老项目升级成本高
  • 需要最广泛的兼容性

4.3 两者都支持

使用 Zipoly(zipoly.netlify.app)可以:

  1. 选择 Meshopt 引擎
  2. 如果 Meshopt 不可用,自动降级到 Draco
  3. 一键压缩,无需手动配置

五、Three.js 中使用 Meshopt

5.1 基础配置

javascript 复制代码
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js'

const loader = new GLTFLoader()
loader.setMeshoptDecoder(MeshoptDecoder)

loader.load('/model.glb', (gltf) => {
  scene.add(gltf.scene)
})

5.2 配合 KTX2 纹理

javascript 复制代码
import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'

const ktx2Loader = new KTX2Loader()
ktx2Loader.setTranscoderPath('/basis/')
ktx2Loader.detectSupport(renderer)

const loader = new GLTFLoader()
loader.setMeshoptDecoder(MeshoptDecoder)
loader.setKTX2Loader(ktx2Loader)

loader.load('/model.glb', (gltf) => {
  scene.add(gltf.scene)
})

5.3 压缩命令

使用 gltfpack 命令行工具:

bash 复制代码
# 安装
npm install -g gltfpack

# 压缩
gltfpack -i input.glb -o output.glb -cc

# 参数说明
# -cc: 压缩顶点和索引
# -tc: 压缩纹理(KTX2)
# -si 0.5: 简化到 50%

六、Zipoly 一键压缩

6.1 操作步骤

  1. 下载 Zipoly:zipoly.netlify.app
  2. 导入 GLB 文件
  3. 选择"Web 3D 场景"预设(默认 Meshopt)
  4. 点击"开始优化"

6.2 压缩效果

模型 原始大小 Draco Meshopt
产品模型 45MB 8.2MB 6.8MB
角色模型 32MB 5.1MB 4.2MB
场景模型 120MB 22MB 18MB

七、性能对比测试

7.1 测试环境

  • 浏览器:Chrome 120
  • 设备:MacBook Pro M1
  • Three.js:r160

7.2 测试结果

指标 Draco Meshopt 提升
解码时间 28ms 4ms 7x
内存占用 45MB 32MB 29%
首帧时间 120ms 85ms 29%

总结

Meshopt 在解码速度和压缩率上都优于 Draco,是 Web3D 项目的首选压缩方案。

推荐工作流:

  1. 使用 Zipoly 压缩模型(默认 Meshopt)
  2. Three.js 中配置 MeshoptDecoder
  3. 配合 KTX2 纹理压缩,实现最佳性能

官网:zipoly.netlify.app 在线版:zipoly-web.netlify.app

相关推荐
90后的晨仔9 小时前
从 H5 到 uni-app:一篇写给前端小白的"翻译指南"
前端·vue.js·前端框架
陈随易10 小时前
moon,apt和yum之外linux系统命令安装新选择
前端·后端·程序员
IT小盘10 小时前
13-企业Prompt模板-角色任务约束与输出格式
java·前端·prompt
徐小夕11 小时前
开源!我用SQLite + DuckDB打造了一款可视化AI问数平台
前端·算法·github
leslie11811 小时前
babel笔记
前端
用户0595401744612 小时前
Redis 记忆存储踩坑实录:一个并发写入 Bug 让我排查了 4 小时
前端·css
小徐_233312 小时前
Wot UI 2.3.0 发布:二维码组件来了,Open Wot 与 wot-starter 同步更新
前端·微信小程序·uni-app
kyriewen13 小时前
Claude自己跑出去hack了3家公司——我为什么还在用它写代码
前端·ai编程·claude
IT_陈寒13 小时前
SpringBoot自动配置的坑,这次真踩疼我了
前端·人工智能·后端
子兮曰13 小时前
AI 浏览器 Agent 的安全困局:当自动化工具可以偷走你的登录态
前端·人工智能·后端