Skip to content

一个 GPU 压缩纹理降级的 GLTF 扩展,及其 CLI 生成工具

Notifications You must be signed in to change notification settings

deepkolos/gltf-gpu-compressed-texture

Repository files navigation

gltf-gpu-compressed-texture

一个用于 GPU 压缩纹理降级的 GLTF 扩展,以及批量 CLI 转换工具,适用于THREEGLTFLoaderDEMO 地址扩展定义

加载策略

  1. 优先使用 pvrtc,因为其体积上面与 jpg 相差不大,与 PNG 有较大优势(done
  2. 无透明通道优先使用 etc1 (done 大小的策略可覆盖这条
  3. 根据 bitmap 与所支持的压缩纹理格式体积比值判断是否使用压缩纹理(done 选择大小小于 bitmap 2 倍的压缩纹理
  4. 少图片和小图片 UI 线程 decode,否则在 Worker 线程 decode(done 少图片

TODO

  1. 多进程 encode (done
  2. 输出加载各压缩纹理类型体积统计 (done
  3. 按一定优先级规则 GPU 压缩纹理类型 (优先 pvrtc
  4. 支持输出 GLB 格式
  5. basisu zstd 参数可自定义(basisu done
  6. 少图片使用 UI 线程 decode, 多图片使用 worker decode (done, 但是对于少贴图模型需要更详细规则
  7. 支持 ETC2 格式
  8. 生成 bitmap 大小,用于策略判断 (done
  9. 可自定义加载策略 (done
  10. 类 tfjs tf.profile 运行时反馈式优化,即运行时遍历出加载时间最少的策略并记录起来(针对当前场景而言)
  11. 升级 zstd wasm 构建参考zstandard-wasm (done DamagedHelmet 95ms -> 81ms 大概15%的提升

命令行使用

使用之前请确保zstdbasisu已经在 PATH 里面

> npm i gltf-gpu-compressed-texture -S
# 查看帮助
> gltf-tc -h

  -h --help                                                              显示帮助
  -i --input [dir] [?outdir] [?compress] [?mipmap] [?basisuArgs]         把gltf所使用纹理转换为GPU压缩纹理并支
持fallback

Examples:
  gltf-tc -i ./examples/glb ./examples/zstd
  gltf-tc -i ./examples/glb ./examples/no-zstd 0
  gltf-tc -i ./examples/glb ./examples/no-mipmap 1 false
  gltf-tc -i ./examples/glb ./examples/no-zstd-no-mipmap 0 false
  gltf-tc -i ./examples/glb ./examples/zstd 1 true "-uastc"

# 执行
> gltf-tc -i ./examples/glb ./examples/zstd

done: 9855ms    image3.png      法线:false      sRGB: true
done: 15337ms   image2.png      法线:true       sRGB: false
done: 16189ms   image0.png      法线:false      sRGB: true
done: 16894ms   image1.png      法线:false      sRGB: false
done: 600ms     FINDI_TOUMING01_nomarl1.jpg     法线:true       sRGB: false
done: 612ms     FINDI_TOUMING01_Basecoler.png   法线:false      sRGB: true
done: 1317ms    lanse_banzi-1.jpg       法线:false      sRGB: true

cost: 18.88s
compress: 1, BoomBox summary:
  bitmap: 10.53MB (0.00MB)
  astc  : 6.12MB (-4.41MB)
  bc7   : 6.08MB (-4.44MB)
  dxt   : 2.56MB (-7.97MB)
  pvrtc : 1.87MB (-8.66MB)
  etc1  : 1.41MB (-9.12MB)

compress: 1, Fendi_banzi_blue summary:
  bitmap: 0.33MB (0.00MB)
  astc  : 0.52MB (0.19MB)
  bc7   : 0.53MB (0.19MB)
  dxt   : 0.23MB (-0.10MB)
  pvrtc : 0.20MB (-0.14MB)
  etc1  : 0.21MB (-0.12MB)

Done in 19.43s.

只要设置 -comp_level 6,这个脚本就是烤机工具

NPM 包使用

import {
  GLTFLoader,
  CompressedTexture,
  WebGLRenderer,
} from 'three-platfromzie/examples/jsm/loaders/GLTFLoader';
import { GLTFGPUCompressedTexture } from 'gltf-gpu-compressed-texture';

const gltfLoader = new GLTFLoader();
const renderer = new WebGLRenderer();
const scene = new Scene();

gltfLoader.register(parser => {
  return new GLTFGPUCompressedTexture({
    parser,
    renderer,
    CompressedTexture: THREE.CompressedTexture,
    loadStrategy: GLTFGPUCompressedTexture.DEFAULT_STRATEGY,
  });
});

gltfLoader.loadAsync('./examples/zstd/BoomBox.gltf').then(gltf => {
  scene.add(gltf.scene);
});

性能情况

运行环境 Chrome 93, CPU Intel I9 10900 ES 版,核显 HD630
加载 BC7 格式,use ImageBitmapLoader,THREE r129,localhost,disable cache: true

模型 参数 load render 总耗时 模型大小 依赖大小
banzi_blue gltf-tc zstd no-mimap no-worker 36.10ms 1.60ms 37.70ms 506kb 22.3kb
banzi_blue gltf-tc no-zstd mimap no-worker 25.80ms 1.50ms 27.30ms 2.2mb 22.3kb
banzi_blue gltf-tc zstd mimap no-worker 37.90ms 1.60ms 39.50ms 648kb 22.3kb
banzi_blue gltf ktx2 uastc 534.70ms 1.70ms 536.40ms 684kb 249.3kb
banzi_blue glb 32.80qms 6.00ms 38.80ms 443kb
banzi_blue gltf 27.70ms 4.90ms 32.60ms 446kb
BoomBox gltf-tc zstd mipmap worker 153.50ms 23.70ms 177.20ms 6.6mb 22.3kb
BoomBox gltf-tc zstd mipmap no-worker 241.10ms 9.40ms 250.50ms 6.6mb 22.3kb
BoomBox glb ktx2 uastc 506.10ms 9.30ms 515.40ms 7.1mb 249.3kb
BoomBox glb 156.10ms 89.50ms 245.60ms 11.3mb
BoomBox gltf 120.20ms 58.80ms 179.00ms 11.3mb

由于 banzi_blue 贴图小于 4 张,所以在 UI 线程 decode zstd,因为 worker 传数据也会有不少耗时 对比使用的 KTX2Loader 全部 zstd decode 是在 UI 线程,decode in Web Worker PR已提交 依赖大小 22.3kb 是从线上 DEMO 取得,http-server --gzip 不太好使

可以明显看到相比于 KTX2+uastc 的压缩纹理方案,从加载耗时和依赖大小,有大幅优势,模型大小也有不少优势
同时也可以看到 BoomBox gltf-tc zstd mipmap worker load+render 耗时,与 gltf 耗时 相差不大,但是模型大小有大幅优势

但是这些都是相对于 PNG 和压缩纹理对比,从 DamagedHelmet 可看到 jpg 的体积对比,jpg 有十分巨大的体积优势

compress: 1, DamagedHelmet summary:
  bitmap: 3.06MB (0.00MB)
  astc  : 11.49MB (8.42MB)
  bc7   : 11.52MB (8.46MB)
  dxt   : 5.15MB (2.09MB)
  pvrtc : 4.12MB (1.05MB)
  etc1  : 4.71MB (1.65MB)

MI 8 下和火狐的测试数据可以查看 screenshots 目录

微信 webview 下 BoomBox 均比 glb/gltf 快,应该属于异常,chrome 下表现正常,banzi_blue 则稍慢一些,KTX2 的方案依然很慢

示例还有 FlightHelmetCases,但是图片资源太大,火狐 lost context, chrome render process 崩溃

参考

  1. ASTC 纹理压缩格式详解
  2. 你所需要了解的几种纹理压缩格式原理

赞助

如果项目对您有帮助或者有适配需求,欢迎打赏

赞赏码

About

一个 GPU 压缩纹理降级的 GLTF 扩展,及其 CLI 生成工具

Resources

Stars

Watchers

Forks

Packages

No packages published