GLB loading with meshopt compressed textures


I’m currently trying to get a meshopt compressed .glb to load. For this I use the code from this project: load-glb-model-with-meshopt
This code seems to be taken from the viewer itself (as stated in the comments).

The loading of the .glb works, as long as the compressed .glb doesn’t also contain compressed textures. Meaning as long as you don’t use meshopts commands for compressing textures -tc (and optionally -tq x you are fine).
However, I exactly want and need these compressed textures. Manually compressing every texture, loading and assigning them seems to be unnecessarily difficult.

Here’s the error thrown by the code and the viewer because of the compressed textures.
My project:

Is there a workaround for compressed textures with meshopt?

this is possibly the issue
We have a fix which we’ll be releasing soonish (as a preview build perhaps tomorrow, we’re just testing it)

1 Like

Hey, just curious. Is this supposed to work now?

I believe so … try your glb in the viewer: PlayCanvas glTF Viewer

Ah yes it works in the viewer, nice.

However the same .glb does not work for me when I’m trying to load it with code. I believe you can view this?

it’s likely you need to add meshopt wasm module / set it up, see here Compressed glb file is not loading in the editor - #7 by Chris

The wasm module is in the MeshOpt folder below right?

The current engine version (1.50.X) doesn’t support compressed textures in GLBs. You will need to use the preview version (1.51.X) which can be selected in project settings.

You will also need a more updated version of the Basis WASM files as the ones that get imported into the Editor are outdated.

Example here with updated Basis library. Don’t forget to fork and change the engine version to preview:


Yeah cool, that works!

However, when you untick preload on the .glb there is some kind of Offset error.

launch.js:15178 RangeError: Offset is outside the bounds of the DataView
    at DataView.getUint32 (<anonymous>)
    at parseGlb (playcanvas-1.51.4.dbg.js:33300)
    at parseChunk (playcanvas-1.51.4.dbg.js:33360)
    at Function.parseAsync (playcanvas-1.51.4.dbg.js:33426)
    at Object.callback (playcanvas-1.51.4.dbg.js:33515)
    at Http._onSuccess (playcanvas-1.51.4.dbg.js:2187)
    at Http._onReadyStateChange (playcanvas-1.51.4.dbg.js:2139)
    at XMLHttpRequest.xhr.onreadystatechange (playcanvas-1.51.4.dbg.js:2075)

You will have to load the GLB asset before the script loads the GLB container. The script assumes that the asset is already loaded.

It is as you say! My load script works even without preload ticked once I updated the basis library and switched to the newer version :slight_smile:

Any plans on adding compression options for .glbs inside the editor now?

Sorry for the late reply on this.

Plans yes. Schedule, no unfortunately. Some more details here:

We’ve had some people downloading build to publish to their web site, and runing command line tool on the glb files in the zip to compress them. This can be automated as well using REST API.


Ah that could be a way to do it!

I tried it by simply exchanging the glb with the compressed one on the server and it downloads but doesn’t show.
This error gets thrown:

playcanvas-stable.min.js:6 RangeError: Invalid typed array length: 1849440
    at new Uint8Array (<anonymous>)
    at playcanvas-stable.min.js:6:610592
    at Tl.r (playcanvas-stable.min.js:6:610208)
    at Tl (playcanvas-stable.min.js:6:610516)
    at playcanvas-stable.min.js:6:611633
    at c (playcanvas-stable.min.js:6:611123)
    at playcanvas-stable.min.js:6:611551
    at o (playcanvas-stable.min.js:6:611002)
    at playcanvas-stable.min.js:6:611189
    at playcanvas-stable.min.js:6:611590

Any quick fix or will this not work?

Does the compressed one load in the viewer? Do you have WASM modules for meshopt set up? Try this with debug version of the engine to get some callstack (min version is not very handy here), or even put breakpoint and see what the problem might be.

Ah so you need the WASM modules, makes sense actually.
So it’s not something you can just do by exchanging the glb. How would you even set this up? Is there a tutorial for that?

Not without the meshopt WASM modules that you can find in the project you linked in the first post:

(You can right click and copy the folder and then paste into yours)

I’m not sure how meshopt works but assuming you take a GLB, run it through the meshopt tool to get a GLB back out: You can use the REST API to download the build (that has all the WASM modules in the project), unzip it, parse config.json, for each GLB asset filepath, convert the GLB file and zip up the whole project again.

I do something like this here in the REST API tools on one-page.js

Direct link to the code:

Thanks for the links, but this seems too time consuming for me right now. Maybe if this method is sometimes in the future simpler to manage I’d use it.
Loading the compressed glb in via custom script has to suffice for now.

1 Like