加载中...
GLTF压缩的技术方法
发表于:2023-08-02 | 分类: 前端 WebGL

GLTF压缩的技术方法

gltf-transform、gltfpack和gltf-pipeline都是用于处理glTF文件的工具库,但它们在功能和使用上有一些不同之处。下面是它们的纵向对比:

1、gltf-transform:

  • 功能:gltf-transform是一个功能强大的glTF处理库,它提供了对glTF文件进行灵活、高级编辑和优化的功能。它支持修改glTF的结构、添加自定义扩展、处理节点层次结构、更改材质、优化缓冲数据、添加、删除和替换属性等。

  • 优点:提供了高级编辑和优化功能,非常适合需要进行复杂处理和定制化操作的场景。

  • 缺点:功能相对较复杂,需要一定的学习成本。

使用 glTF-Transform 压缩为 KTX

安装完所有内容后,您现在可以压缩 glTF 文件。有不同的压缩选项可用;这里有一些可以帮助您入门的方法。

方法一:UASTC + ETC1S

使用 UASTC 压缩法线和遮挡/粗糙度/金属度 (ORM) 纹理,使用 ETC1S 压缩所有其他纹理:

gltf-transform uastc input.glb output1.glb --level 4 --rdo 4 --slots "{normalTexture,occlusionTexture,metallicRoughnessTexture}" --zstd 18 --verbose

gltf-transform etc1s output1.glb output2.glb --quality 255 --verbose
  • gltf-transform是工具本身。
  • uastc是压缩方法。这比 etc1 压缩得更少,但往往会产生更少的块状伪影。与 ETC1S 相比,它在具有不相关 RGB 值的纹理(例如 ORM 贴图)上产生的伪像更少。
  • input.glb是您要压缩的文件,其中包含 PNG 和/或 JPEG 纹理。重命名它以匹配正在压缩的任何文件。
  • output1.glb是要保存的临时文件,带有新的 KTX 纹理。上面代码块中的第一步将使用 UASTC 仅压缩法线凹凸和遮挡粗糙金属纹理,其余部分保持原始格式。然后第二步将使用 ETC1S 压缩剩余的纹理。
  • --level 4是一个高品质的环境。它产生可达到的最高质量,但速度可能非常慢。如果太慢,请尝试 3。
  • --rdo 4是中等质量设置,但会生成较小的文件。完整范围为 [.001, 10.0]。较低的值会产生较高质量/较大的 LZ 压缩文件,较高的值会产生较低质量/较小的 LZ 压缩文件。一个不错的尝试范围是 [.25, 10]。对于法线贴图,尝试范围为 [.25, .75]。
  • --slots允许您使用以下设置包含或排除纹理类型:
  • "{normalTexture,occlusionTexture,metallicRoughnessTexture}"告诉 glTF Transform 使用 UASTC 仅压缩普通纹理和 ORM 纹理。要查看 GLB 中的纹理槽列表,请使用命令gltf-transform inspect input.glb这将显示每个纹理的尺寸和文件大小。这对于识别名称特别有用,--slots因此您可以将不同的压缩设置应用于不同的纹理类型。
  • --zstd 18应用超级压缩。压缩级别范围为[1, 22],默认18,0为不压缩。值越低速度越快,但压缩程度越低。应谨慎使用 20 以上的值,因为它们需要更多内存。
  • --verbose逐步显示 glTF Transform 正在做什么。在 Windows 上,压缩期间没有进度指示器,只有闪烁的光标。--verbose作为进度条很有用,可确保其正常工作,并帮助您确定是否包含了正确的选项。
  • output1.glb是上面代码块第一步的输出,现在在第二步中使用 ETC1S 压缩其余纹理。
  • output2.glb第二步是最终的完全压缩模型,所有纹理均为 KTX 格式。将其重命名为所需的任何输出名称。
  • --quality 255第二步告诉 glTF-Transform 对 ETC1S 使用最高质量,但它应用较少的压缩,并且压缩文件需要更长的时间。当质量比转换速度更重要时使用此选项。

请注意,这是两个单独的命令。第一个命令仅使用 UASTC 压缩法线和 ORM 映射。然后第二个命令使用 ETC1S 压缩所有剩余的纹理。仅在第一个命令完成后才启动第二个命令。第二个命令不需要--slots "!{normalTexture,occlusionTexture,metallicRoughnessTexture}"参数来省略法线/ORM 映射,因为 glTF-Transform 不会重新压缩现有的 KTX 文件。它仅压缩非 KTX 纹理。

2、gltfpack:

  • 功能:gltfpack是一个专注于减小glTF文件大小的工具,主要通过压缩纹理和几何信息来实现。它支持使用Draco压缩几何信息,将纹理转换为KTX格式,并进行大小调整等。

  • 优点:简单易用,专注于文件大小优化,适合快速优化glTF文件。

  • 缺点:功能相对较为单一,只适合文件大小优化,不提供其他高级编辑功能。

  • 用法

    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

    默认情况下,gltfpack 在优化场景时会做出某些假设,例如,属于非动画节点的网格可以合并在一起,并且有一些默认值代表精度和大小之间的权衡,这些默认值适合大多数用例。但是,在某些情况下,生成的.gltf文件需要保留某种方式供应用程序操作各个场景元素,而在其他情况下,优化精度或大小更为重要。gltfpack 有一组丰富的命令行选项来控制其行为的各个方面,完整列表可通过gltfpack -h.

    经常使用以下设置来减少生成的数据大小:

    -cc:生成压缩的 gltf/glb 文件(需要EXT_meshopt_compression

    • -tc:使用 BasisU 超级压缩将所有纹理转换为 KTX2(需要KHR_texture_basisu并且可能需要-tp标志以与 WebGL 1 兼容)
    • -mi:在序列化对相同网格的引用时使用网格实例(需要EXT_mesh_gpu_instancing
    • -si R:以三角形计数比率 R 简化网格(默认值:1;R 应介于 0 和 1 之间)

    以下设置经常用于限制某些优化:

    • -kn:保持命名节点和网格附加到命名节点,以便命名节点可以在外部进行转换
    • -km:保留命名材质并禁用命名材质合并
    • -ke:保留额外数据
    • -vpf:使用浮点位置量化而不是默认的定点(这会导致更大的位置数据,但不会插入具有反量化变换的新节点;使用此选项时,也建议-cc

    代码如下:

  • import { MeshoptDecoder } from './meshopt_decoder.module.js';
    
    var loader = new GLTFLoader();
    loader.setMeshoptDecoder(MeshoptDecoder);
    loader.load('pirate.glb', function (gltf) { scene.add(gltf.scene); });
    
    
    const  ktx2Loader = new  KTX2Loader ()
    // .setTranscoderPath('js/libs/basis/')
    .setTranscoderPath ('node_modules/three/examples/js/libs/basis/')
    .detectSupport (_this.renderer );
    // const loader = new GLTFLoader().setPath('./public/three/models/gltf/cc_tc/');
    const  loader = new  GLTFLoader ();
    loader.setKTX2Loader (ktx2Loader );
    

3、gltf-pipeline:

  • 功能:gltf-pipeline是一个综合性的glTF处理工具库,提供了一系列方法用于处理glTF文件,包括优化、拆分、合并、纹理压缩、处理模型等。
  • 优点:功能比较全面,可以进行优化、压缩、拆分、合并等多种处理操作。
  • 缺点:在某些复杂的场景中,可能没有gltf-transform提供的高级编辑能力。

综合来看,如果你需要对glTF文件进行复杂的编辑和定制化处理,gltf-transform是一个不错的选择。如果你只关注文件大小的优化,gltfpack提供了简单高效的方法。而gltf-pipeline提供了综合性的功能,是一个比较全面的处理工具库,适合在多种场景下使用。根据具体的需求和应用场景,选择合适的工具库进行处理会更加有效和方便

下一篇:
各种移动GPU压缩纹理的使用方法