Skip to content

Releases: zeux/meshoptimizer

v1.1

02 Apr 16:08
dc9d09e

Choose a tag to compare

meshoptimizer 1 1

This release introduces two new major features, meshlet compression and opacity micromaps, as well as several small features and improvements. Highlights:

A new meshlet codec can compress meshlet topology (micro-index and vertex reference data), exploiting inherent locality and designed for extremely fast CPU decompression. Each meshlet is encoded independently, allowing flexibility in structuring the runtime storage and parallelism. Meshlets can be decoded into common runtime formats (3 or 4 bytes per triangle, 2 or 4 bytes per vertex reference) for direct GPU consumption. For further size savings, the output of the encoder can be compressed using general purpose compressors such as Zstandard. Decoder is heavily optimized and can directly target write-combined memory; you can expect it to run at 7-10 GB/s on modern desktop CPUs. For applications that do streaming processing on the GPU, an example compute shader decoder is provided and can reach 150+ GB/s on RTX 5070.

Opacity micromap rasterization is now supported; a set of functions can generate hardware ready opacity micromap data from mesh UVs and a texture with an alpha channel. The resulting micromap data can be used directly in Vulkan via VK_EXT_opacity_micromap or in DirectX via DXR1.2. Each triangle is subdivided according to its UV footprint into a 4^N microtriangle grid; micro-triangles can use a 2-state (1 bit) or 4-state (2 bits) representation. 4-state representation is useful to accelerate shader invocations to confirm hit opacity via a texture lookup, whereas 2-state representation (or a forced 2-state fallback for a 4-state representation) can be used to completely eliminate shader invocations and reach maximum tracing performance. To minimize the memory overhead, the maps are reused between triangles using a per-triangle OMM index buffer with generated special indices for triangles with consistent state.

The majority of the work on the core library in this release has been sponsored by Valve; thank you!

Library improvements

  • New experimental functions for meshlet encoding, meshopt_encodeMeshlet/meshopt_encodeMeshletBound/meshopt_decodeMeshlet/meshopt_decodeMeshletRaw, can be used to compress meshlet topology
  • New experimental functions for opacity micromaps, meshopt_opacityMapMeasure/meshopt_opacityMapRasterize/meshopt_opacityMapCompact/meshopt_opacityMapEntrySize, can be used to rasterize opacity micromaps from UV coordinates and a texture alpha channel
  • New experimental function, meshopt_optimizeMeshletLevel, optimizes meshlet order further to achieve higher compression ratios (with level 3 recommended for good results)
  • New experimental function, meshopt_extractMeshletIndices, extracts meshlet micro-index buffer and vertex references from a cluster index buffer
  • New experimental option for meshopt_simplify* functions, meshopt_SimplifyRegularizeLight, enables regularization with a smaller factor to reduce impact on geometric quality
  • New experimental flag for vertex_lock array in meshopt_simplifyWith* functions, meshopt_SimplifyVertex_Priority, allows tagging individual vertices so that they are more likely to be preserved
  • Improve performance of bounds computation via meshopt_computeMeshletBound/meshopt_computeClusterBounds by 50% on typical inputs
  • Remove index_count % 3 assertions from meshopt_generateVertexRemap/meshopt_remapIndexBuffer/meshopt_optimizeVertexFetch
  • Improve alpha encoding precision in meshopt_encodeFilterColor, reducing error by ~40%
  • Add support for ARM64EC architecture when building with MSVC

Additional improvements

  • Add optimize_clusters_level parameter to clodConfig in clusterlod.h to optimize clusters for better compression
  • Add demo/meshletdec.slang shader as an example for how to decode new meshlet encoding in a compute shader
  • Fix several bugs in gltfpack that could result in invalid outputs in various corner cases (blend weights, joint indices, clearcoat roughness)
  • Reduce MeshoptDecoder JavaScript module size by ~5% and improve several filters to decode ~5% faster
  • Fix imprecise assertions and memory overallocation in MeshoptClusterizer JavaScript module

Thanks to @aalekhm for contributions to this release!

v1.0

08 Dec 16:29
73583c3

Choose a tag to compare

This release focuses on improvements to clusterization, simplification and partitioning algorithms, as well as stabilization - with the exception of permissive simplification mode, all other library functionality introduced in prior releases is now considered stable.

Highlights:

Clusterization algorithms (meshopt_buildMeshlets/meshopt_buildMeshletsFlex, meshopt_buildMeshletsSpatial) are now faster and, in the case of spatial clusterization, produce higher-quality clusters for vertex-bound meshlets. Additionally, meshlet builders no longer align local index data to 4 bytes, which simplifies memory management and removes alignment restrictions on triangle limits. When cluster partitioning is required, meshopt_partitionClusters now produces better partitioning for disconnected clusters which improves quality of DAGs for hierarchical clusterization.

Speaking of hierarchical clusterization, a new single-header library clusterlod.h is now developed and maintained alongside meshoptimizer. This library implements continuous level of detail by generating a hierarchy of clusters that are progressively grouped and simplified, similarly to Nanite. It leverages meshoptimizer algorithms for internal processing, and can either be used as-is or as a starting point for implementing a custom solution - the code is structured to be easy to understand and modify. Some relevant improvements are described in Billions of triangles in minutes blog post.

New simplification features added in the last release have seen further quality improvements as well; both meshopt_simplifyWithUpdate and the meshopt_SimplifyPermissive option now generate higher-quality outputs. Permissive mode option specifically is still considered experimental, and future releases may improve or change behavior further.

All other experimental library functions and options have been promoted to stable status. This means that future releases will be API compatible (code will continue compiling), ABI compatible (code can link to a shared library build of meshoptimizer which can then be updated independently) and behavior compatible (results may improve in future releases, but these improvements should not require adjustments to the calling code) as far as current 1.0 functionality is concerned.

The vertex encoding functions (meshopt_encodeVertexBuffer/meshopt_encodeVertexBufferLevel) now encode v1 data by default. This can be overridden for applications that need to produce data in v0 format, especially if producing data for EXT_meshopt_compression extension which only supports v0. This version only switches the encoding default; support for encoding and decoding v0/v1 will be provided in perpetuity.

gltfpack now supports the new KHR_meshopt_compression extension via -cz option (or -ce khr which allows specifying compression level independently; -cz is equivalent to -ce khr -cc), which provides better compression compared to the existing EXT_meshopt_compression extension. Note that loader support for this extension is not yet widely available, and by default gltfpack continues to use EXT_meshopt_compression when compression is requested.

Finally, JavaScript bindings have been updated to use ES modules instead of CommonJS modules, which may require adjustments to import paths. For the MeshoptDecoder module, a CommonJS variant meshopt_decoder.cjs is still provided for compatibility (but note a different file extension, required for correct handling by some bundlers).

The majority of the work on the core library in this release has been sponsored by Valve; thank you!

Upgrade notes

  • meshopt_encodeVertexBuffer now uses format version 1 by default, which requires meshoptimizer v0.23 or later to decode. Applications that encode data for EXT_meshopt_compression glTF extensions need to switch to version 0 by using meshopt_encodeVertexVersion or meshopt_encodeVertexBufferLevel functions.
  • Meshlet builders (meshopt_buildMeshlets and other variants) no longer align local index data for each meshlet by 4 bytes; applications that use writePackedPrimitiveIndices4x8NV intrinsic (from NV_mesh_shader extension) may need to align each meshlet manually.

Library improvements

  • Switch to vertex encoding version 1 by default; meshopt_encodeVertexVersion/meshopt_encodeVertexBufferLevel can be used to encode data using version 0 if needed
  • Remove 4b alignment padding and triangle alignment requirements for meshopt_buildMeshlets* functions
  • meshopt_buildMeshletsFlex, meshopt_buildMeshletsSpatial, meshopt_decodeFilterColor, meshopt_encodeFilterColor and meshopt_generatePositionRemap functions are now stable
  • meshopt_simplifyWithUpdate and meshopt_simplifySloppy functions, as well as meshopt_SimplifyRegularize flag, are now stable
  • meshopt_partitionClusters now returns slightly tighter partitions (now containing up to partition_size + partition_size / 3 clusters)
  • meshopt_partitionClusters now merges spatially adjacent partitions if vertex positions are provided, even if the input clusters do not share vertices
  • Remove support for negative cone_weight from meshopt_buildMeshletsFlex (this was an experimental feature, superseded by meshopt_buildMeshletsSpatial)
  • Significantly improve performance of meshopt_buildMeshlets* functions for sparse mesh subsets
  • Improve quality of simplified meshes when using meshopt_simplifyWithUpdate (reduced position deformation, attributes are now updated on more vertices, attribute continuity is preserved in permissive mode)
  • Improve quality of simplified meshes when using meshopt_SimplifyPermissive for attribute discontinuities without protection bits
  • Improve performance of meshopt_simplify* functions when using meshopt_SimplifySparse flag on very sparse mesh subsets
  • Improve clusterization quality for meshopt_buildMeshletsSpatial on meshes with vertex-bound meshlets
  • Improve performance of meshopt_buildMeshletsSpatial by 10-25% on x64 and AArch64
  • Improve performance of meshopt_buildMeshlets by 20-30% on meshes with many attribute discontinuities
  • Improve performance of meshopt_decodeFilter* function family by 15-45% on AArch64
  • Improve performance of meshopt_decodeFilterQuat by 10-20% on x64
  • Fix a rare (and benign) division by zero in meshopt_simplifySloppy
  • Guarantee bounded recursion depth for all recursive functions (meshopt_buildMeshletsFlex, meshopt_buildMeshletsSpatial, meshopt_partitionClusters)

gltfpack improvements

  • Implement support for draft KHR_meshopt_compression extension (via -ce khr or -cz command line options)
  • Preserve per-instance colors (_COLOR_0) when using mesh instancing
  • Fix duplicate texture encoding with Basis/WebP (when -tc and -tw command line options are used together)
  • Improve precision of texture coordinate encoding when using -vtf on meshes with UV mapping issues
  • Warn when texture coordinate quantization error is significant and -vtf is not specified
  • Validate output file extension before processing to prevent unnecessary work

JavaScript improvements

  • Replace CommonJS modules with ES modules; this may require adjustments to import paths. For decoder, meshopt_decoder.cjs is still provided for compatibility (note a different extension).
  • Switch to vertex encoding version 1 in MeshoptEncoder.encodeVertexBuffer by default; for compatibility with EXT_meshopt_compression extension, MeshoptEncoder.encodeGltfBuffer continues to default to v0
  • Add MeshoptSimplifier.generatePositionRemap function
  • Add MeshoptClusterizer.buildMeshletsFlex and MeshoptClusterizer.buildMeshletsSpatial functions
  • Add optional version argument to MeshoptEncoder.encodeGltfBuffer to support encoding v1 data

Thanks to @minitoine, @OfficialKris and @ynnob for contributions to this release!

v0.25

20 Aug 15:43
6daea46

Choose a tag to compare

This release contains many improvements to the meshoptimizer library, with a particular focus on simplification algorithms, as well as several new gltfpack features. Highlights:

New simplification function meshopt_simplifyWithUpdate optimizes vertex positions and attributes for higher-quality LODs, and a new permissive simplification mode enabled via meshopt_SimplifyPermissive flag allows simplification of faceted meshes with selective preservation of attribute discontinuities. Additionally, meshopt_SimplifyRegularize flag improves tessellation quality and appearance of deformable meshes, sloppy simplifier (meshopt_simplifySloppy) implements vertex locking support, and multiple improvements to the main simplification algorithms improve quality at the same triangle count by default.

gltfpack now supports encoding WebP images via -tw option, which enables further reduction in compressed asset sizes at some memory cost at runtime. Additionally, gltfpack exposes permissive simplification via -sp option, which can simplify meshes further while preserving appearance much better compared to aggressive simplification.

The majority of the work on the core library in this release has been sponsored by Valve; thank you!

Note: gltfpack development is done in spare time; potential corporate sponsors should feel free to reach out via e-mail.

Library improvements

  • New experimental function, meshopt_simplifyWithUpdate, enhances attribute-aware simplification by computing optimal positions/attributes for the simplified mesh, allowing to increase quality of lower levels of detail at additional vertex memory cost
  • New experimental simplification flag, meshopt_SimplifyPermissive, allows simplification across attribute discontinuities, with optional support for protecting individual vertices with bit flag meshopt_SimplifyVertex_Protect on lock flags specified via vertex_lock
  • New experimental simplification flag, meshopt_SimplifyRegularize, results in more regular tessellation at some cost to shape preservation, which is particularly valuable for deformable meshes
  • New experimental function, meshopt_generatePositionRemap, creates a table mapping vertices to the canonical vertex with the same position (which can be used to prepare data for various algorithms like simplification and partitioning)
  • New experimental color filter, exposed via meshopt_encodeFilterColor/meshopt_decodeFilterColor, can be used to further improve compression ratio on quantized RGBA streams
  • meshopt_simplifySloppy now has an extra argument, vertex_lock, allowing to lock individual vertices to preserve mesh boundaries
  • meshopt_analyzeCoverage, meshopt_computeSphereBounds, meshopt_encodeVertexBufferLevel, meshopt_generateVertexRemapCustom, meshopt_partitionClusters and meshopt_spatialClusterPoints functions are now stable
  • meshopt_simplifyPrune function and meshopt_SimplifyPrune flag are now stable
  • Simplification now iteratively removes zero-area triangles that can arise in complex topological cases, reducing the triangle count at no quality impact
  • Improve simplification restrictions around certain seam edges which can slightly reduce the overall triangle count
  • Improve simplification quality of seam/border edge loops
  • Improve simplification of flat (planar) regions resulting in higher quality tessellation
  • Improve tracking of component error during simplification which could previously result in insufficient simplification when meshopt_SimplifyPrune was enabled
  • Improve performance of meshopt_optimizeOverdraw by ~15%
  • Rework meshopt_Allocator callback storage to make it compatible with C++20 modules and shared library builds (when MESHOPTIMIZER_ALLOC_EXPORT is defined)

gltfpack improvements

  • Implement option -tw which compresses textures to WebP format, resulting in smaller files at the expense of more memory consumption compared to Basis Universal.
  • Implement option -sp which enables permissive simplification, allowing the simplifier to collapse edges across attribute discontinuities (as a much higher quality alternative to aggressive simplification)
  • Implement option -vi to use interleaved vertices instead of separate streams; this partially disables compression in -cc mode
  • Improve simplification quality of deformable (skinned/morphed) meshes
  • Target simplification error is now automatically scaled based on mesh size for scenes containing multiple meshes
  • Attribute aware simplification is now enabled by default; option -sv is no longer necessary but is maintained for compatibility
  • Fix transparent material optimization when materials are used on meshes with vertex alpha
  • Improve cross-platform support for CMake builds (for BSD systems and cross-compilation workflows)
  • CMake option for Basis Universal builds has been renamed to MESHOPT_GLTFPACK_BASISU_PATH for consistency
  • Linux release binaries are now built on older Ubuntu versions to improve glibc compatibility
  • macOS release binaries are now split between architectures (Intel & Apple Silicon)

JavaScript improvements

  • Add support for v1 vertex encoding via MeshoptEncoder.encodeVertexBufferLevel
  • Add MeshoptClusterizer.computeSphereBounds and MeshoptSimplifier.simplifyPrune functions
  • Add experimental support for color filtering via MeshoptDecoder.decodeVertexBuffer and MeshoptEncoder.encodeColor
  • MeshoptSimplifier now supports experimental simplifySloppy, simplifyWithUpdate functions and experimental "Regularize" / "Permissive" flags for simplify*
  • Fix invalid assertions when calling simplifyWithAttributes with no attributes

Thanks to @jopadan and @toge for contributions to this release!

v0.24

12 Jun 16:03
7b2d4f4

Choose a tag to compare

This release contains many improvements to the meshoptimizer library and some gltfpack fixes! Some highlights:

New meshlet builder (meshopt_buildMeshletsSpatial) designed for raytracing workloads optimizes meshlets using SAH cost and can be used with NVidia cluster acceleration structure extensions. The generated meshlets follow the same format and data layout as other meshlet builders, thus the functions can be used interchangeably based on the expected usage of a given mesh.

An assortment of new experimental functions in various areas of the library help reindex meshes with tolerance (meshopt_generateVertexRemapCustom), remove isolated components after isosurface meshing (meshopt_simplifyPrune), rasterize point clouds via compute using spatially optimized clusters (meshopt_spatialClusterPoints), and implement adaptive view dependent distance based culling for small objects (meshopt_analyzeCoverage).

Cluster partitioning (meshopt_partitionClusters) now accepts vertex positions as an optional input, improving spatial locality of returned partitions.

The majority of the work on the core library in this release has been sponsored by Valve; thank you!

Note: gltfpack development is done in spare time; potential corporate sponsors should feel free to reach out via e-mail.

Library improvements

  • New experimental function, meshopt_buildMeshletsSpatial, generates meshlets that are optimized for ray tracing workloads and can be used with NVidia cluster acceleration structure extensions
  • New experimental function, meshopt_generateVertexRemapCustom, generates vertex remap for reindexing using a custom comparison function for vertex attributes, which can be used to weld vertices with per-attribute tolerance
  • New experimental function, meshopt_simplifyPrune, removes connected components under the specified threshold, which is useful for simplification and isosurface cleanup
  • New experimental function, meshopt_spatialClusterPoints, subdivides the input point cloud into uniformly sized chunks, which is useful for compute driven rendering
  • New experimental function, meshopt_analyzeCoverage, returns rasterized coverage from three cardinal axes, which is useful for distance based culling
  • meshopt_encodeVertexBufferLevel now accepts encoding version as an optional parameter for multi-threaded multi-versioned encoding
  • meshopt_partitionClusters now accepts vertex positions as an optional input, which helps reduce spatial bounds for partitions
  • meshopt_partitionClusters is now ~2x faster on typical inputs
  • meshopt_spatialSort* functions now use more precise Morton codes, yielding more accurate order for large meshes
  • meshopt_decodeIndexBuffer has been optimized to decode ~10% faster when using MSVC
  • meshopt_computeMeshletBounds and other bounds functions now compute 1-2% tighter bounding spheres
  • meshopt_analyzeOverdraw now correctly computes depth information which results in more accurate statistics
  • meshopt_simplify now correctly handles negative zero components in input positions
  • meshopt_generateProvokingIndexBuffer and meshopt_spatialSortTriangles are now stable
  • CMake option MESHOPT_STABLE_EXPORTS allows building shared library without experimental functions
  • Improve code compatibility with VS2013

gltfpack improvements

  • Improve performance for inputs with abnormally large vertex accessors
  • Lines are now supported in input .OBJ files

Thanks to @axmand and @pm4rtx for contributions to this release!

v0.23

14 Mar 15:57
3e9d1ff

Choose a tag to compare

This release contains many improvements to the meshoptimizer library and some gltfpack enhancements! Some highlights:

Vertex codec v1 (enabled via meshopt_encodeVertexVersion(1)) provides increased compression ratio, faster decompression speed, and customizable compression levels. Depending on input data, compressed data can be up to 5-10% smaller and decode up to 10% faster. Additionally, decoding has been further optimized for modern AArch64 CPUs, achieving 20% higher decoding speed on Apple Silicon for both versions (up to 30% overall improvements for v1).

Meshlet builder (meshopt_buildMeshlets) now generates fewer disconnected clusters, improving rasterization performance by up to 5% on certain meshes. Additionally, this algorithm now exposes extra options (via meshopt_buildMeshletsFlex) to create more axis-aligned clusters and further reduce disconnected clusters. This benefits use cases like clustered ray tracing (for Nvidia RTX) and hierarchical clusterization. For hierarchical clusterization, a new experimental algorithm, meshopt_partitionClusters, can be used to build the cluster hierarchy, and meshopt_computeSphereBounds can be used to compute the necessary bounds.

The majority of the work on the core library in this release has been sponsored by Valve; thank you!

Note: gltfpack development is done in spare time; potential corporate sponsors should feel free to reach out via e-mail.

Library improvements

  • meshopt_encodeVertexVersion now supports version 1, which results in better compression ratio and faster decoding
  • Default vertex codec version does not change in this version; applications that produce compressed data for glTF storage should call meshopt_encodeVertexVersion(0) to ensure that future library upgrades do not alter the encoding
  • An experimental function, meshopt_encodeVertexBufferLevel, allows adjusting the compression level to balance between compression ratio and encoding speed (only available for version 1)
  • meshopt_decodeVertexBuffer has been further optimized for some AArch64 systems, with up to 20% speedup on Apple Silicon
  • meshopt_decodeVertexVersion/meshopt_decodeIndexVersion allow inspecting the encoded version of the compressed buffer
  • meshopt_simplifyWithAttributes uses a more careful evaluation of attribute error on attribute seams, improving attribute quality
  • meshopt_buildMeshlets now produces significantly fewer disconnected clusters, resulting in ~5% rasterization performance improvement in some cases
  • meshopt_buildMeshlets is significantly faster and uses less memory for sparse mesh subsets (e.g. groups of clusters)
  • meshopt_buildMeshlets* functions now support max_vertices=256 (up from 255)
  • An experimental algorithm, meshopt_buildMeshletsFlex, allows more flexible cluster sizing and using axis-aligned bounds, which can improve clusterization quality for hierarchical clusterization and/or raytracing clusters
  • An experimental algorithm, meshopt_computeSphereBounds, allows computing sphere bounds for groups of spheres or large meshes (as a complement to meshopt_computeMeshletBounds which is only useful for meshlets)
  • An experimental algorithm, meshopt_partitionClusters, allows partitioning a set of clusters into larger groups, which is useful for hierarchical simplification
  • meshopt_quantizeHalf/meshopt_quantizeFloat are now extern "C" to allow proper use from non-C++ code
  • meshopt_simplifyWithAttributes, meshopt_simplifyPoints, meshopt_optimizeMeshlet, and meshopt_EncodeExpClamped are now stable
  • CMake option MESHOPT_INSTALL allows disabling installation targets when building the library

gltfpack improvements

  • Improve UV seam preservation for meshes with UV mirroring
  • Implement support for KHR_materials_diffuse_transmission extension
  • Allow disabling animation resampling by specifying frequency 0 (-af 0)
  • Allow per-texture-class control for texture scaling (-ts) and limit (-tl)
  • Preserve primitive extras when -ke is specified
  • Warn when position quantization error is significant and -vpf is not specified

JavaScript changes

  • simplifyWithAttributes and simplifyPoints no longer require MeshoptSimplifier.useExperimentalFeatures
  • npm version of gltfpack now requires Node 18+ due to a WASI update

Thanks to @hankarun and @JulienIcon, as well as Nvidia engineers, for contributions to this release!

v0.22

25 Oct 17:26
4affad0

Choose a tag to compare

This release contains many improvements to the meshoptimizer library and some gltfpack enhancements!

Notably, meshopt_simplifyWithAttributes has seen significant improvements to attribute handling, meshopt_simplify* algorithms now produce results with fewer triangles and better quality on meshes with complex topology, meshopt_buildMeshlets produces slightly more optimal clusterization, and gltfpack will often produce smaller outputs due to geometry deduplication and improved quantization.

The majority of the work on the core library in this release has been sponsored by Valve; thank you!

Note: gltfpack development is done in spare time; potential corporate sponsors should feel free to reach out via e-mail.

Library improvements

  • A new algorithm, meshopt_generateProvokingIndexBuffer, generates an index buffer that can be used to efficiently render visibility buffers by using nointerpolate attributes
  • meshopt_simplifyWithAttributes now uses an improved attribute metric that mixes better with positional error and results in more intuitive weighting
  • meshopt_simplifyWithAttributes now properly tracks attribute errors across attribute discontinuities
  • meshopt_simplifyWithAttributes no longer spends time or memory on attributes with weight 0, and allows up to 32 scalar attributes
  • meshopt_simplifyWithAttributes now has better support for vertex_lock if the input lock flags are inconsistent on discontinuities
  • meshopt_simplify* can now collapse some edges that were previously restricted which improves quality and reduces minimum reachable triangle count
  • meshopt_simplify* now support component pruning via a new experimental meshopt_SimplifyPrune option which disregards interior topology and removes components entirely
  • meshopt_simplify* are now ~5-10% faster on large meshes due to better memory access patterns and improved scheduling
  • meshopt_simplify* use more accurate computations to improve quality and convergence
  • meshopt_simplifyPoints uses an improved color metric that results in more intuitive weighting
  • meshopt_buildMeshlets uses improved heuristics to produce up to ~1% fewer meshlets on large meshes with fewer disconnected meshlets
  • meshopt_decodeFilter* and meshopt_encodeFilter* family of functions are now stable
  • meshopt_encodeFilterExp supports an extra experimental mode, meshopt_EncodeExpClamped, which can be used on texture coordinates for a better balance between quality and size

gltfpack improvements

  • Mesh geometry is now deduplicated based on its contents, which can significantly reduce the size of the output in some cases and improve instancing efficiency
  • When quantization is enabled, normals/tangents are quantized before reindexing which can significantly improve the output size/efficiency without affecting quality
  • Optionally keep unused vertex attributes if -kv is specified; together with -vtf this can be used to preserve UV mapping on assets without materials/textures
  • Simplification error can now be specified via a new -se command line option
  • Fix handling of files with Unicode paths on Windows (starting from Windows 10)
  • Fix incorrect mesh merging across scene boundaries for multi-scene assets
  • Fix rare cases where output JSON would be invalid due to Inf/NaN values

JS improvements

  • A new module, MeshoptClusterizer, exposes meshlet clustering and bounds computation functionality (by @JolifantoBambla)
  • simplifyWithAttributes now correctly supports vertex_lock argument and expects it to be Uint8Array (instead of JS array) when specified

Thanks to @JolifantoBambla and @Ono-Sendai for contributions to this release!

v0.21

25 Jun 19:13

Choose a tag to compare

This release contains improvements to the meshoptimizer library and many gltfpack enhancements! Notably, the introduction of sparse and absolute error simplification options in meshopt_simplify as well as per-vertex locking in meshopt_simplifyWithAttributes improves Nanite-style processing pipelines, meshlet optimization increases rasterization performance further on NVidia hardware, and gltfpack now preserves most data compression / optimization extensions which makes it easier to compose with other glTF processing tools.

Library improvements

  • Introduce experimental meshopt_optimizeMeshlet algorithm that should be used to optimize individual meshlets for rendering efficiency (mostly affects NVidia hardware but can be used for other vendors as well)
  • meshopt_simplifyWithAttributes now takes an additional optional array, vertex_lock, which allows specifying 1 for individual vertices that should not be moved during simplification (note that this is an interface change and will require source changes; the API continues to be experimental and may see further changes in future releases)
  • meshopt_simplify options now support a new flag, meshopt_SimplifySparse, which significantly increases simplification performance when simplifying small subsets of a larger mesh (note that the error in this mode is relative to the subset, as such use of meshopt_SimplifyErrorAbsolute is recommended for consistency)
  • meshopt_simplify options now support a new flag, meshopt_SimplifyErrorAbsolute, which treats target error and the result error as absolute (in mesh coordinate space) instead of relative to mesh extents
  • Simplifier now tries harder to prevent triangle flips at a minimal cost to simplification performance and efficiency
  • meshopt_optimizeVertexCache now needs ~5% less memory and is ~7% faster on Windows
  • MESHOPT_SOVERSION CMake option can be used to customize .so version for shared library builds

gltfpack improvements

  • Implement support for KHR_texture_basisu and EXT_texture_webp extensions in the input files; the extensions and images will be preserved as is regardless of compression flags
  • Implement support for EXT_mesh_gpu_instancing extension in the input files; instanced meshes will be preserved regardless of -mi flag
  • Implement support for EXT_meshopt_compression extension in the input files; files using this extension will be automatically decompressed (and recompressed if -c/-cc is specified)
  • Implement support for KHR_materials_dispersion extension
  • Implement attribute aware simplification: when -sv flag is specified, vertex colors and normals are used during simplification to improve appearance
  • Image names are now preserved when present in the input file
  • Improve texture compression when using UASTC format: textures are now a little smaller by default, and using low quality levels via -tq allows to push compressed size further down at the expense of some quality loss
  • Improve behavior of simplification with extremely low factors (eg -si 0)
  • Improve behavior of quantization when the input file is already quantized
  • Improve behavior for textures that are missing on disk when the output file is a GLB
  • Automatically fix incorrect MIME type for PNG/JPEG input textures
  • Normal attributes are removed for meshes that use unlit materials to reduce size
  • Normals can be optionally stored without quantization by using -vnf flag (only needed for rare edge cases involving morph targets, prefer -vn to increase normal quality)

Thanks to @ruby0x1, @sciecode and @oisyn for contributions to this release!

v0.20

02 Nov 19:53

Choose a tag to compare

This release contains new algorithms and improvements to the meshoptimizer library, many gltfpack enhancements and JS library updates! Importantly, an experimental meshopt_simplifyWithAttributes algorithm can take attribute information into account for better appearance, and gltfpack now copies texture files to the output folder when the output format is .gltf (which can be disabled via -tr option).

Note that attribute-aware simplification is still in development, and there are some known issues with attribute weighting, discontinuities and geometry preservation, so the interface and behavior is subject to change in future releases. Issue #158 can be tracked for development progress.

Library improvements

  • The default index encoding version for meshopt_encodeIndexBuffer and meshopt_encodeIndexSequence has been updated to 1. Version 1 has been supported since meshoptimizer 0.14 and is the version that is part of glTF EXT_meshopt_compression extension; if legacy version 0 is needed, this can be overridden via meshopt_encodeIndexVersion.
  • Introduce experimental meshopt_simplifyWithAttributes algorithm that takes attribute error into account when running simplification at some cost to geometric error and simplification memory and performance
  • Implement meshopt_dequantizeHalf which can reverse the quantization done by meshopt_quantizeHalf for cases when the data is needed on the CPU
  • meshopt_simplify now requires ~25% less memory for large meshes
  • meshopt_optimizeVertexCache is now ~15% faster for large meshes
  • meshopt_simplifyPoints now consumes less memory and supports per-point colors during simplification; the algorithm is still experimental but will likely be stabilized in a future release. The interface has changed to accommodate optional color attribute input.
  • meshopt_simplify now prevents triangle flipping better in planar regions (although some issues remain, tracked in #346)
  • meshopt_remapVertexBuffer is now up to 4x faster for deinterleaved streams with small stride
  • meshopt_spatialSortRemap is no longer experimental (which means it has a stable API like most other functions)
  • Fixed vertexfilter.cpp compilation with Emscripten when using Wasm SIMD and SIMD emulation flags

gltfpack improvements

  • By default, when targeting .gltf files, gltfpack now copies texture files to the output folder. This can be changed by using the new -tr option (which also allows to keep texture file references when targeting .glb files).
  • Implement support for KHR_materials_anisotropy extension
  • Improve processing performance for large geometry-heavy glTF files
  • Preserve custom integer ID attributes (_ID, _BATCHID and _FEATURE_ID_n)
  • Fix mesh instancing (-mi) transform handling for scenes with non-uniform scale & rotation
  • Improve mesh instancing (-mi) efficiency on some CAD exports by relaxing mesh merging rules
  • Improve animation error analysis for translation tracks when nodes have a large scale
  • Identical texture glTF objects are now merged together, which results in significant size/performance improvements on some exports
  • Improve point cloud optimization and simplification using the library enhancements
  • Implement optional support for floating-point texture coordinate quantization via -vtf; this is occasionally useful on scenes with very large texture tiling factors
  • Improve support for .obj file parsing: vertex colors are now preserved and more data from .mtl materials is preserved

JavaScript improvements

  • Introduce reorderPoints function to MeshoptEncoder; this function is recommended for use with point clouds to reduce data size and improve render locality
  • Improve support for JavaScript minifiers when using MeshoptDecoder and WebWorkers
  • Improve MeshoptDecoder useWorkers behavior: calling the function twice no longer leaks workers, and useWorkers(0) can be used to reclaim WebAssembly instance memory
  • Introduce experimental simplifyPoints and simplifyWithAttributes functions to MeshoptSimplifier; these functions may change interface/implementation significantly in future releases and require setting useExperimentalFeatures to true.

Thanks to @LorenRoosendaal, @1d10t and @Light7734 for contributions to this release!

v0.19

29 Apr 18:36
fbe26ff

Choose a tag to compare

This release contains several meshoptimizer and gltfpack fixes/improvements as well as tweaks for the JavaScript library. Notably, -vpf mode in gltfpack can simplify integration into applications that are very sensitive to the scene graph structure as it allows to preserve it better than the default quantization mode does without resorting to disabling quantization entirely.

Library improvements

  • Improve meshopt_decodeVertexBuffer performance by 5-10% for Intel/AMD and 15-25% for ARM
  • Improve scoring heuristic for meshopt_buildMeshlets which results in ~2% fewer meshlets with ~5% smaller radius on average
  • Improve meshopt_encodeFilterExp performance by ~3x and make the encoder more flexible with the new mode parameter
  • Fix compilation issues with Android NDK 19c and some Emscripten build configurations

gltfpack improvements

  • Add floating-point position quantization (-vpf) which removes the need for dequantization transforms at some cost to geometry size
  • Add support for border locking during simplification via -slb which can fix gaps between different meshes
  • When using -vpf or -noq, meshes will usually be attached directly to their source nodes without new intermediate nodes
  • Skin names are now preserved when present in the input file
  • Fix material optimization when both a metallic-roughness model and a specular-glossiness model was used with inconsistent transparency

JavaScript improvements

  • Add exports and update type definitions for MeshoptSimplifier
  • Reduce memory consumption of MeshoptSimplifier by 3-4x
  • Add WebWorker support to MeshoptDecoder (via MeshoptDecoder.useWorkers)

Thanks to @donmccurdy, @LilyWangLL, @daemyung, @DavidKorczynski, @rafern, @Kuranes and @mosra for contributions to this release!

v0.18

01 Aug 02:57
e62c41e

Choose a tag to compare

This release contains several gltfpack fixes/improvements as well as small improvements to the simplifier, and support for simplifier in the JavaScript library.

Importantly, gltfpack now uses basis_universal as a library to implement ETC1S and UASTC texture compression. This means that external executables like basisu/toktx are no longer necessary, and compression of complex scenes is much faster due to support for parallel compression using optimized job pool to maximize resource allocation, but it also means that node.js version of gltfpack can no longer compress textures - native gltfpack binary should be used instead.

Library improvements

  • Add options bitmask to meshopt_simplify that can be used to specify meshopt_SimplifyLockBorder option; this option is useful when multiple chunks of a single mesh are simplified independently, as it makes sure the simplified versions will connect without gaps
  • Fix vertex classification around degenerate triangles which improves simplification quality in rare cases
  • Added MESHOPTIMIZER_ALLOC_CALLCONV build setting (fixes #403)
  • JavaScript version of meshoptimizer library now supports mesh simplification via mesh_simplifier module

gltfpack improvements

  • Add support for KHR_materials_emissive_strength
  • Add support for KHR_materials_iridescence
  • Switch to parallel texture compressor using internal Basis encoder, and stop supporting texture compression via external executables
  • Add command line option -tj that can override the degree of parallelism used during texture compression
  • Add command line option -tl that can limit the texture width/height during texture compression
  • Support texture masks in -tc option which allows to only compress some textures as ETC1S
  • Implement support for normalized attributes during quantization; texture coordinates now use normalized integers, and positions can use normalized integers with -vpn command line option
  • Preserve interpolation type for STEP animation tracks
  • Sort bone influences by weight, not by index, which allows renderers to drop last few bone influences in shader LODs
  • Optimize .obj parsing to reduce memory consumption, yielding 2-3x reduction in total memory consumption for some large .obj files