Skip to content

v1.0

Latest

Choose a tag to compare

@zeux zeux released this 08 Dec 16:29
· 6 commits to master since this release
73583c3

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!