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

相关推荐
子兮曰20 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰20 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万20 小时前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝20 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋21 小时前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁21 小时前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄1 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95271 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大1 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师1 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端