meshoptimizer

repository·master·Indexed 26 days ago

https://github.com/zeux/meshoptimizer

A library providing algorithms to optimize triangle meshes for GPU rendering, including vertex cache, overdraw, and vertex fetch optimization, as well as reducing mesh complexity and storage overhead. It includes gltfpack, a command-line tool for optimizing glTF files for size and speed, and JavaScript/WebAssembly modules for decoding and encoding mesh buffers.

Tokens
22.4K
Snippets
49
Records
119
Agent score
91%

What's inside meshoptimizer

  1. License and Attribution

    master

    meshoptimizer is licensed under the MIT License. To comply with the license, you must include attribution in your user-facing product documentation or credits.

    Example attribution text: Uses meshoptimizer. Copyright (c) 2016-2026, Arseny Kapoulkine

  2. Understand API stability and experimental features

    master

    Meshoptimizer distinguishes between stable and experimental APIs:

    • Stable APIs (MESHOPTIMIZER_API): Guaranteed API and ABI compatibility. Existing calls will compile and link, and behavior will not change significantly. Note that algorithm output may improve in future versions, potentially changing results.
    • Experimental APIs (MESHOPTIMIZER_EXPERIMENTAL): Interfaces may change (breaking compilation), behavior may change significantly, or they may be removed in future versions. It is recommended to check release notes when updating.

    Configuration Options:

    • To emit compiler warnings when using experimental APIs, define MESHOPTIMIZER_EXPERIMENTAL as __attribute__((deprecated)).
    • When building a shared library with CMake, set MESHOPT_STABLE_EXPORTS to only export stable APIs. This allows you to update the shared library without recompiling the application code.
  3. Install meshoptimizer

    master

    You can install meshoptimizer by cloning the repository or downloading a release archive. It is also available through various package managers including Vcpkg, Conan, and several Linux distributions (ArchLinux, Debian, FreeBSD, Nix, Ubuntu).

    git clone -b v1.2 https://github.com/zeux/meshoptimizer.git
  4. Install gltfpack

    master

    You can install gltfpack in two ways:

    1. Native Binary (Recommended): Download pre-built binaries from the Releases page. Native binaries are preferred as they support texture compression, run faster, and handle larger files better than the npm version.
    2. npm Package: Install via npm using npm install -g gltfpack (or your preferred package manager).
  5. Handle deinterleaved geometry with multiple vertex streams

    master

    If your geometry uses multiple vertex streams (e.g., separating positions from normals/UVs for depth pre-passes), you must use the Multi variants of certain functions and remap each stream individually.

    Vertex Remapping for Multiple Streams

    To generate a vertex remap for multiple streams, use meshopt_generateVertexRemapMulti. After generating the remap, you must call meshopt_remapVertexBuffer once for each individual vertex stream to produce the correctly reindexed data.

    Shadow Indexing

    Use meshopt_generateShadowIndexBufferMulti as a replacement for the standard shadow indexing function when working with multiple streams.

    Vertex Fetch Optimization

    Instead of using meshopt_optimizeVertexFetch on a single buffer, it is recommended to use meshopt_optimizeVertexFetchRemap and then call meshopt_remapVertexBuffer for each stream.

    Vertex Compression

    When compressing vertex data, use meshopt_encodeVertexBuffer on each vertex stream separately. This allows the encoder to better utilize correlations between attribute values within each specific stream.

    meshopt_Stream streams[] = {
        {&unindexed_pos[0], sizeof(float) * 3, sizeof(float) * 3},
        {&unindexed_nrm[0], sizeof(float) * 3, sizeof(float) * 3},
        {&unindexed_uv[0], sizeof(float) * 2, sizeof(float) * 2},
    };
    
    std::vector<unsigned int> remap(index_count);
    size_t vertex_count = meshopt_generateVertexRemapMulti(&remap[0], NULL, index_count, index_count, streams, sizeof(streams) / sizeof(streams[0]));
  6. Build meshoptimizer

    master

    meshoptimizer is distributed as a C/C++ header (src/meshoptimizer.h) and C++ source files (src/*.cpp). You can integrate it into your project using one of two methods:

    1. CMake: Build the library as a standalone project or include it in your CMake project.
    2. Manual Integration: Add the required source files directly to your build system. The source files are organized so you only need to add the specific algorithm files you intend to use. They are designed to build without special compilation options on all major compilers.

    For amalgamated builds, you may concatenate the source files into a single .cpp file.

  7. Use permissive simplification to collapse attribute seams

    master

    By default, the simplifier respects attribute discontinuities (seams). If a mesh has many seams (e.g., faceted/flat-shaded meshes), the simplifier may get "stuck".

    To allow collapsing vertices across these discontinuities, use the meshopt_SimplifyPermissive option with meshopt_simplifyWithAttributes.

    Fine-grained Control: To prevent the simplifier from collapsing critical seams (like UV seams or sharp creases) while in permissive mode, use the vertex_lock array with the meshopt_SimplifyVertex_Protect flag for specific vertices.

  8. Compress point clouds

    master

    You can use the vertex encoding algorithms to compress point clouds. For optimal efficiency, follow these steps:

    1. Spatial Sort: Sort points using meshopt_spatialSortRemap to improve locality.
    2. Remap: Apply the sort to all attribute streams using meshopt_remapVertexBuffer.
    3. Quantize: Quantize attributes (e.g., 16-bit fixed point for positions, 8-bit for color).
    4. Encode: Use meshopt_encodeVertexBuffer on the quantized data.
    std::vector<unsigned int> remap(point_count);
    meshopt_spatialSortRemap(&remap[0], positions, point_count, sizeof(vec3));
    
    // for each attribute stream
    meshopt_remapVertexBuffer(positions, positions, point_count, sizeof(vec3), &remap[0]);
  9. Use gltfpack CLI to optimize glTF files

    master

    Run the gltfpack command-line tool on an input .gltf, .glb, or .obj file. By default, it optimizes meshes for vertex fetch and transform cache, quantizes geometry, merges meshes to reduce draw calls, and prunes the node tree.

    To see all available options, run gltfpack without arguments or use gltfpack -h.

    gltfpack -i scene.gltf -o scene.glb
  10. Follow the meshoptimizer core pipeline order

    master

    To maximize rendering efficiency, apply optimizations in the following specific order:

    1. Indexing
    2. Vertex cache optimization
    3. Overdraw optimization (optional)
    4. Vertex fetch optimization
    5. Vertex quantization
    6. Index filtering
    7. Shadow indexing (optional)
  11. Build gltfpack from source

    master

    To build a full version of gltfpack with texture compression support, you must provide paths to basis_universal and libwebp during the CMake configuration.

    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
    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