GLTFLoader: Implement support for KHR_meshopt_compression#32163
GLTFLoader: Implement support for KHR_meshopt_compression#32163donmccurdy merged 3 commits intomrdoob:devfrom
Conversation
This change brings in new features required for new glTF meshopt extension, notably decoding v1 vertex/attribute blobs and color filter support. The module is fully compatible with all prior encoded data. When using gzip/Brotli compression, the .js file got ~1.5 KB larger: gzip, before: 6432 bytes gzip, after: 8051 bytes (+25%) Brotli, before: 5754 bytes Brotli, after: 7203 bytes (+25%) While the increase is noticeable, the increase is close to typical CDN response *headers* (~1 KB), and any reasonable glTF asset will see higher gains from new compression so this should be worthwhile. If we ever decide to shrink things further, it's possible to split the decoder module as around 25% of the cost is supporting legacy browsers without Wasm SIMD support; removing that would save ~2 KB for both gzip and Brotli.
Since the extension uses the exact same JSON structure as EXT variant, and meshopt decoder automatically decodes v1 attribute blobs and automatically picks up color filters through filter name, the only thing we need to do is to register the extension code twice for two different names.
|
Thank you @zeux! Support for WASM SIMD looks quite good... ... assuming support depends only on the runtime/browser, and not the device/CPU? If that's the case, then I think dropping non-SIMD support would be reasonable. But for three.js' purposes, the Meshopt decoder is already much smaller than Draco or Basis decoders, so I'm not complaining about +1.5 kb here. :) It'd be nice to have the draft at "Review Draft" or "Release Candidate" status before we merge, but open to other suggestions as well. Work in progress for glTF Transform: |
There is some dependency on CPU features too - I'm not sure caniuse report incorporates this. I would not expect this to notably affect the usage percentage. Regardless, this is more of a possibility in the future; I agree that for now the increase seems fine relative to other projects, it's just visible when looking at it relative to the older size :) Agreed wrt extension status, I posted this PR a draft for awareness + to move the extension along (hopefully existence of draft implementations encourages extension review progress!). |
This updates meshopt_decoder.module.js to latest version from 1.0 that will be released soon. The changes are minor in code size and behavior relative to 0.25 update and this is just to ensure that we're using the stable 1.0.
|
I've updated the PR with the 1.0 version of the decoder module; it's more or less the same in terms of size as the original comments indicate (+-20 bytes post deflate); the update is not essential but it's nice to depend on the latest stable release. |
|
Per KhronosGroup/glTF#2517 (comment) this extension is in "review draft" and so hopefully this PR can be reviewed now. For testing, assets from this comment could be used: KhronosGroup/glTF#2517 (comment) (glTF-Sample-Assets will get test assets in the future). gltfpack 1.0 also supports this extension via Here's a synthetic cube grid asset that uses various combinations of modes too, and should look approximately like this:
|
|
For completeness, here's an updated version of the asset used by three.js 'webgl_loader_gltf_compressed' example; it can be copied to @donmccurdy Please let me know if you have any comments! |
donmccurdy
left a comment
There was a problem hiding this comment.
Thank you @zeux! Changes look good to me. Given the "review draft" status, applicability and adoption of the EXT extension, and minimal added complexity of the implementation, I think we can merge support for KHR_meshopt_compression now.

Specification: KhronosGroup/glTF#2517
Since the extension uses the exact same JSON structure as EXT variant,
and meshopt decoder automatically decodes v1 attribute blobs and
automatically picks up color filters through filter name, the only thing
we need to do is to register the extension code twice for two different
names.
To decode new v1 vertex streams and color filters, meshopt_decoder
needs to be updated to v0.25; the updated module is of course fully
compatible with all prior encoded data.
When using gzip/Brotli compression, the .js file got 1.5 KB larger:
This increase is significant on a relative basis, but given that CDN response
headers often approach 1 KB, it's perhaps reasonable in absolute terms. If this
becomes a problem in the future, it is possible to shrink the file in various ways,
for example removing support for pre-SIMD Wasm engines would remove 2 KB
post-gzip.