关于GLTF模型压缩
1、GLTF格式介绍
1) glTF是一种3D内容的格式标准,由Khronos Group管理(Khronos Group还管理着OpenGL系列、OpenCL等重要的行业标准);
2)glTF的设计是面向实时渲染应用的,尽量提供可以直接传输给图形API的数据形式,不再需要二次转换;
3) glTF对OpenGL ES、WebGL非常友好;
4) glTF的目标是:3D领域的JPEG;
5) 作为一个标准,自2015年10月发布(glTF 1.0)以来,已经得到了业界广泛的认可,你可以相信它的水平;
6)glTF目前最新版本为2.0已于2017年6月正式发布。
GLTF具体的数据存储格式可以去官方网站上看:https://www.khronos.org/gltf/ 有GLTF+bin+Texture以及GLB组织格式,其中GLB是二进制,GLTF是Json方式。
2、GLTF模型压缩方式
1)Draco
扩展:KHR_draco_mesh_compression
用于GLTF扩展以及由 Google 开发的开源库,提供3D图形mesh和点云的压缩和解压。它的目标是提升3D图形的存储和传输效率。它压缩顶点位置、法线、颜色、纹理坐标和任何其他通用顶点属性,从而提高在网络上传输 3D 内容的效率和速度。
使用Draco的好处:
- 减少空间的占用, 减少网络传输量,该优点是它的核心好处。
- Draco的解压算法,网页端提供了wasm的解压算法,一定程度的降低了网页端解压消耗
使用Draco的缺憾:
- 可能性能提升也并没有期望中那么大,这个跟数据源的特点有关,不能得到保证,特别对于纹理压缩不是很理想。
- 模型画质的损失是肉眼可观的,需要总体权衡。
压缩方式:
gltf-pipeline -i scene.glb -o scene-processed.glb -d
详细参考 https://github.com/CesiumGS/gltf-pipeline
2)Meshopt
扩展:KHR_mesh_quantization
压缩方式:
gltfpack -i male.glb -o male-processed.glb -cc
3)MeshQuan
扩展:EXT_meshopt_compression
压缩方式:
gltfpack -i male.glb -o male-processed.glb
KHR_mesh_quantization和EXT_meshopt_compression可以使用同一个工具gltfpack
> npm i -g gltfpack
# gltfpack命令行工具是C项目构建出WASM执行的,目测未来会有更多wasm这类项目产出
# KHR的优化版的basis trancoder是使用assemblyscript编译成wasm
# 转成KHR_mesh_quantization
> gltfpack -i model.glb -o out.glb
# EXT_meshopt_compression只需加个-cc参数即可
> gltfpack -i model.glb -o out.glb -cc
4)其他
- EXT_mesh_gpu_instancing
现 Three.js 的 GLTFLoader 尚未支持,Babylon.js 的BABYLON.GLTF2.Loader.Extensions 支持 - 还有一些纹理优化的插件:
- KHR_texture_basisu
- EXT_texture_webp
详细参考:https://github.com/KhronosGroup/KTX-Software
3、在Three.js中使用与测试
1)Draco使用方式
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
const loader = new GLTFLoader()
// 创建解码器实例
const dracoLoader = new DRACOLoader()
// 设置解压库文件路径
dracoLoader.setDecoderPath(DECODER_PATH)
// 加载解码器实例
loader.setDRACOLoader(dracoLoader)
loader.load(MODEL_FILE_PATH, (gltf) => {
// ....
})
2)MeshOpt使用方式
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js'
const loader = new GLTFLoader()
loader.setMeshoptDecoder(MeshoptDecoder)
loader.load(MODEL_FILE_PATH, (gltf) => {
// ....
})
3)MeshQuan使用方式
mport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
const loader = new GLTFLoader()
loader.load(MODEL_FILE_PATH, (gltf) => {
// ....
})
4、性能分析与对比
1)Draco
| Model | Before Compression | After Compression(Used gltfpack's -tc -cc flag) |
| Korean Public Payphone 01 | 6.23MB | 1.58MB (-74.64%) |
2)MeshOpt
| Model | Before Compression | After Compression (Used gltfpack's -tc -cc flag) |
| Vintage Pocket Watch | 5.95MB | 1.37MB (-76.97%) |
3)KTX2 纹理压缩
KHR_texture_basisu
| Model | Before Compression | After Compression (Used gltfpack's -tc -cc flag) |
| Korean Fire Extinguisher 01 | 5.71MB | 4.13MB (-27.67%) |
5、多个机型测试对比
【TODO】
6、其他
1) obj转gltf
npm install obj2gltf -g