vendored meshoptimizer 1.2(submodule 环境故障改直接 vendor)。Mesh 多 LOD:各级索引连续拼进同一 index buffer(共享顶点,LodRange 区间 选择),解析期 meshopt_simplify 生成链(LOD0=原始,每级目标减半, 相对误差 1e-2,小网格复用上级);都在 worker 线程,加载零额外卡顿。 SceneRenderer 按 (mesh, LOD) 聚合 batch(lookup key = 指针<<8|lod): 主视图按屏占比近似 radius/dist 选级(阈值 10/20 倍半径);阴影级联 按级联序降级(越远越简)。Draw 按 batch.lod 选索引区间。 A/B 对比(100 背包 10×10,RTX 5060 Laptop,vsync off): - 纯背包:LOD 开 93-95 fps / 关 90-107 fps —— 无显著差异 - 加 SunTemple:LOD 开 52-56 / 关 51-55 —— 无显著差异 结论:当前场景瓶颈不在顶点数(5060 顶点吞吐富余),LOD 基础设施 保留(几何复杂资产/低端 GPU/更大场景生效),帧率问题转向 Tracy GPU 时间线定位真实瓶颈。 坑:LodRange 记录"LOD 不足复用最后一级"时 first 不得继续累加 (buffer 无重复数据,累加必越界——VUID-08798 抓的)。
134 lines
9.4 KiB
Markdown
134 lines
9.4 KiB
Markdown
# 📦 gltfpack
|
|
|
|
gltfpack is a tool that can automatically optimize glTF files to reduce the download size and improve loading and rendering speed.
|
|
|
|
## Installation
|
|
|
|
You can download a pre-built binary for gltfpack on [Releases page](https://github.com/zeux/meshoptimizer/releases), or install [npm package](https://www.npmjs.com/package/gltfpack). Native binaries are recommended over npm since they can work with larger files, run faster, and support texture compression.
|
|
|
|
## Usage
|
|
|
|
To convert a glTF file using gltfpack, run the command-line binary like this on an input `.gltf`/`.glb`/`.obj` file (run it without arguments for a list of options):
|
|
|
|
```
|
|
gltfpack -i scene.gltf -o scene.glb
|
|
```
|
|
|
|
gltfpack substantially changes the glTF data by optimizing the meshes for vertex fetch and transform cache, quantizing the geometry to reduce the memory consumption and size, merging meshes to reduce the draw call count, quantizing and resampling animations to reduce animation size and simplify playback, and pruning the node tree by removing or collapsing redundant nodes. It will also simplify the meshes when requested to do so.
|
|
|
|
By default gltfpack outputs regular `.glb`/`.gltf` files that have been optimized for GPU consumption using various cache optimizers and quantization. These files can be loaded by GLTF loaders that support `KHR_mesh_quantization` extension such as [three.js](https://threejs.org/) (r111+) and [Babylon.js](https://www.babylonjs.com/) (4.1+).
|
|
|
|
When using `-c` option, gltfpack outputs compressed `.glb`/`.gltf` files that use meshoptimizer codecs to reduce the download size further. Loading these files requires extending GLTF loaders with support for [EXT_meshopt_compression](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_meshopt_compression/README.md) extension; three.js supports it in r122+ (requires calling `GLTFLoader.setMeshoptDecoder`), Babylon.js supports it in 5.0+ without further setup.
|
|
|
|
For better compression, you can use `-cc` option which applies additional compression; additionally make sure that your content delivery method is configured to use deflate (gzip) - meshoptimizer codecs are designed to produce output that can be compressed further with general purpose compressors. For maximum compression, consider using [KHR_meshopt_compression](https://github.com/KhronosGroup/glTF/pull/2517) extension with a higher compression level (`-cz` option).
|
|
|
|
gltfpack can also compress textures using Basis Universal format stored in a KTX2 container (`-tc` flag, requires support for `KHR_texture_basisu`) or using WebP format (`-tw` flag, requires support for `EXT_texture_webp`).
|
|
|
|
When working with glTF files that contain point clouds, gltfpack automatically processes the point cloud data to reduce the download size to the extent possible. In addition to aforementioned compression options (either `-c` or `-cc` are recommended), gltfpack can also prune point clouds to provide a more uniform density when `-si` option is used.
|
|
|
|
## Decompression
|
|
|
|
When using compressed files, [js/meshopt_decoder.mjs](https://github.com/zeux/meshoptimizer/blob/master/js/meshopt_decoder.mjs) needs to be loaded to provide the WebAssembly decoder module like this:
|
|
|
|
```js
|
|
import { MeshoptDecoder } from './meshopt_decoder.mjs';
|
|
|
|
...
|
|
|
|
var loader = new GLTFLoader();
|
|
loader.setMeshoptDecoder(MeshoptDecoder);
|
|
loader.load('pirate.glb', function (gltf) { scene.add(gltf.scene); });
|
|
```
|
|
|
|
When using Three.js, this module can be imported from three.js repository from `examples/jsm/libs/meshopt_decoder.module.js`.
|
|
|
|
Note that `meshopt_decoder` assumes that WebAssembly is supported. This is the case for all modern browsers; if support for legacy browsers such as Internet Explorer 11 is desired, it's recommended to use `-cf` flag when creating the glTF content. This will create and load fallback uncompressed buffers, but only on browsers that don't support WebAssembly.
|
|
|
|
## Options
|
|
|
|
By default gltfpack makes certain assumptions when optimizing the scenes, for example meshes that belong to nodes that aren't animated can be merged together, and has some defaults that represent a tradeoff between precision and size that are picked to fit most use cases. However, in some cases the resulting `.gltf` file needs to retain some way for the application to manipulate individual scene elements, and in other cases precision or size are more important to optimize for. gltfpack has a rich set of command line options to control various aspects of its behavior, with the full list available via `gltfpack -h`.
|
|
|
|
The following settings are frequently used to reduce the resulting data size:
|
|
|
|
* `-cc`: produce compressed gltf/glb files (requires `EXT_meshopt_compression`)
|
|
* `-tc`: convert all textures to KTX2 with BasisU supercompression (requires `KHR_texture_basisu` and may require `-tp` flag for compatibility with WebGL 1)
|
|
* `-tw`: convert all textures to WebP (requires `EXT_texture_webp`)
|
|
* `-mi`: use mesh instancing when serializing references to the same meshes (requires `EXT_mesh_gpu_instancing`)
|
|
* `-si R`: simplify meshes targeting triangle/point count ratio R (default: 1; R should be between 0 and 1)
|
|
|
|
The following settings are frequently used to restrict some optimizations:
|
|
|
|
* `-kn`: keep named nodes and meshes attached to named nodes so that named nodes can be transformed externally
|
|
* `-km`: keep named materials and disable named material merging
|
|
* `-ke`: keep extras data
|
|
* `-vpf`: use floating-point position quantization instead of the default fixed-point (this results in larger position data, but does not insert new nodes with dequantization transforms; when using this option, `-cc` is recommended as well)
|
|
|
|
## Extensions
|
|
|
|
gltfpack supports most Khronos extensions and some multi-vendor extensions in the input scenes, with newer extensions added regularly. The following extensions are fully supported:
|
|
|
|
- KHR_lights_punctual
|
|
- KHR_materials_anisotropy
|
|
- KHR_materials_clearcoat
|
|
- KHR_materials_diffuse_transmission
|
|
- KHR_materials_dispersion
|
|
- KHR_materials_emissive_strength
|
|
- KHR_materials_ior
|
|
- KHR_materials_iridescence
|
|
- KHR_materials_pbrSpecularGlossiness
|
|
- KHR_materials_sheen
|
|
- KHR_materials_specular
|
|
- KHR_materials_transmission
|
|
- KHR_materials_unlit
|
|
- KHR_materials_variants
|
|
- KHR_materials_volume
|
|
- KHR_mesh_quantization
|
|
- KHR_meshopt_compression
|
|
- KHR_texture_basisu
|
|
- KHR_texture_transform
|
|
- EXT_mesh_gpu_instancing
|
|
- EXT_meshopt_compression
|
|
- EXT_texture_webp
|
|
|
|
Even if the source file does not use extensions, gltfpack may use some extensions in the output file either by default or when certain options are used:
|
|
|
|
- KHR_mesh_quantization (used by default unless disabled via `-noq`)
|
|
- KHR_meshopt_compression (used when requested via `-ce khr` or `-cz`)
|
|
- KHR_texture_transform (used by default when textures are present, unless disabled via `-noq` or `-vtf`)
|
|
- KHR_texture_basisu (used when requested via `-tc` or `-tu`)
|
|
- EXT_meshopt_compression (used when requested via `-c` or `-cc`)
|
|
- EXT_mesh_gpu_instancing (used when requested via `-mi`)
|
|
- EXT_texture_webp (used when requested via `-tw`)
|
|
|
|
gltfpack does not support vendor-specific extensions or custom extensions, including ones defined in [Khronos glTF repository](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Vendor). Unknown extension nodes are discarded from the output.
|
|
|
|
Some Khronos extensions, notably Draco compression and extensions for interactive scenes (interactivity, animation pointer, node selectability/hoverability/visibility), are not supported.
|
|
|
|
## Custom data
|
|
|
|
glTF files may contain custom application-specific data stored outside of custom extensions. gltfpack has limited support for preserving this data.
|
|
|
|
Unknown vertex or instance attributes are generally discarded. While it would be possible to preserve them in theory, many scene transformations and analyses require a full understanding of the attribute semantics - some attributes need to be transformed with the mesh transformation matrix, some need to be adjusted when meshes are merged, some influence how meshes are rendered, etc. However, gltfpack supports some specific attributes that are commonly used in the ecosystem:
|
|
|
|
- Vertex attributes that store integer IDs with names `_ID`, `_BATCHID` or `_FEATURE_ID_n` are preserved as-is. These can be used to identify objects.
|
|
- Instance attribute `_COLOR_0` is preserved as-is. This can be used to provide per-instance color tinting.
|
|
|
|
Additional application-specific data can be stored via the glTF `extras` property. While extras (outside of `asset`) are discarded by default, using the `-ke` option preserves extras in materials, nodes, primitives and scenes.
|
|
|
|
In addition to `asset` extras, gltfpack unconditionally preserves morph target names specified via the `targetNames` property inside `extras` on meshes.
|
|
|
|
## Building
|
|
|
|
gltfpack can be built from source using CMake or Make. To build a full version of gltfpack that supports texture compression, CMake configuration needs to specify the path to https://github.com/zeux/basis_universal fork (branch gltfpack) via `MESHOPT_GLTFPACK_BASISU_PATH` variable, as well as libwebp path via `MESHOPT_GLTFPACK_LIBWEBP_PATH` variable:
|
|
|
|
```
|
|
git clone -b gltfpack https://github.com/zeux/basis_universal
|
|
git clone https://github.com/webmproject/libwebp
|
|
cmake . -DMESHOPT_BUILD_GLTFPACK=ON -DMESHOPT_GLTFPACK_BASISU_PATH=basis_universal -DMESHOPT_GLTFPACK_LIBWEBP_PATH=libwebp -DCMAKE_BUILD_TYPE=Release
|
|
cmake --build . --target gltfpack --config Release
|
|
```
|
|
|
|
## License
|
|
|
|
gltfpack is available to anybody free of charge, under the terms of MIT License (see LICENSE.md).
|