Any3DAny3D
·Any3D Team

3D 模型为什么这么大?

3d-compressiongltfwebglperformance

你的模型在偷偷长胖

你导出了一个 GLB 文件,10MB,感觉还行。传到手机上一打开——白屏、卡顿,甚至直接崩了。

在电脑上没问题,到了手机上就爆炸。这不是代码的锅,而是 3D 模型有一个不太直觉的特性:它在磁盘上和显存里,完全不是一个大小。

一张 JPG 图片在磁盘上可能只有 200KB。但 GPU 不认识 JPG,它只认识原始像素。所以上传到显存之前,这张图会被完全解压。一张 2048x2048 的纹理,解压后要吃掉约 22MB 显存。如果你用了 6 张贴图(albedo、normal、roughness、metallic、AO、emissive),光一个材质就要 132MB。

手机总共可能也就 2-4GB 显存,一个模型的纹理就吃了 3-6%。场景里有 10 个模型呢?

拆开看看,体积都花在哪了

一个典型的 GLB 模型主要由三部分组成:顶点数据纹理贴图,以及元数据和动画。

拿一个真实的 PBR 模型来看:

组成部分具体内容典型占比说明
纹理贴图albedo、normal、roughness、metallic、AO 等70-85%几乎永远是体积大户
顶点数据position、normal、UV、tangent、颜色10-20%取决于模型复杂度
动画数据骨骼、蒙皮、关键帧0-15%有动画才有
其他材质定义、场景结构、相机< 2%可忽略

纹理贴图占了 80% 左右。很多时候你以为要优化的是顶点,但真正占地方的是贴图。

"磁盘小"不等于"显存小"

这可能是理解 3D 性能最关键的一个点。

PNG 和 JPG 是为网络传输设计的——磁盘上很小,下载快。但 GPU 不能直接用它们,必须先完全解压成原始像素。计算方法:

显存占用 = 宽度 * 高度 * 4字节(RGBA) * 1.333(含mipmap)

一张 4096x4096 的 RGBA 纹理:

指标数值
PNG 文件大小~8MB
JPG 文件大小~1.5MB
显存占用(含 mipmap)~87MB

1.5MB 的 JPG,到了显存里变成 87MB。

Mipmap 是什么? GPU 会为纹理生成一系列逐级缩小的版本,从原始大小到 1x1 像素,每个级别是上一级的一半。这让远处的物体渲染更快更清晰,但要多占约 33% 的显存。几乎所有的 3D 应用都会用 mipmap,所以这个开销基本是标配。

所以 PNG/JPG 就像旅行压缩袋——压缩之后小小的方便带,到了目的地得全部撑开。下载快了,但显存一点没省。

显存不够会怎样

不会弹个"显存不足"的提示框。实际情况更糟糕:

  • 移动端:页面白屏,或者系统直接杀掉标签页
  • VR 头显:掉帧。VR 里掉帧不是"有点卡",是会引起眩晕的
  • 桌面端:纹理闪烁、降级、渲染变慢

Reddit 上有个开发者做 WebXR 画廊,往 Quest 上塞了 60 张立体图。一开始正常,后来越来越不稳定直到崩溃。他花了几天查代码,最后发现从来没认真想过 VRAM 这回事——就是一直在往 GPU 里塞 JPG。

压缩的两条路

3D 模型压缩主要分两个方向:

顶点压缩——把顶点坐标、法线、UV 等几何数据用更紧凑的方式存储。比如把 32 位 浮点数换成 16 位整数(这叫 quantization,量化)。代表性方案:DracoMeshOptKHR_mesh_quantization

纹理压缩——让贴图在显存里也保持压缩状态。GPU 在采样时实时解码单个像素,几乎没有性能开销。代表性方案:KTX2 + Basis Universal

顶点压缩纹理压缩
减什么几何数据贴图
典型效果减小 50-90%磁盘减 50-70%,显存减 75%
有损吗是,精度下降是,画质下降
适用场景顶点密集的模型几乎所有 PBR 模型
详见第 2 篇第 3、4 篇

一个常见误区:用了 Draco 压缩顶点就觉得万事大吉。但纹理占了模型 80% 的体积,你把顶点砍一半,整体可能只瘦了 10%。两头都得管。

没有一种方法通吃所有场景

这是整个系列的核心观点:

不同平台、不同设备、不同使用方式,需要不同的压缩策略。

场景首要瓶颈重点关注
桌面 Web 展示下载速度文件大小
移动端浏览器显存纹理压缩
VR 头显显存 + 帧率纹理压缩 + 顶点简化
微信小程序包大小 + 兼容性轻量方案(MeshOpt)
大型场景显存 + draw call全方位压缩 + LOD

后面的每一篇不会只说"用 X 就对了",而是会讲清楚:X 适合什么场景,什么时候反而帮倒忙,什么情况下该用 Y。

下一步

这篇搞清楚了问题。下一篇动手——认识顶点压缩三把工具:量化、MeshOpt 和 Draco。

赞助支持