GLB Instancing in Editor loses extensionsUsed + getFileUrl() incorrect in Launch

I was trying to use GPU instancing following this example:
https://playcanvas.vercel.app/#/graphics/instancing-glb

When using the Editor, I found two issues that appear to be bugs.


1. .glb imported via Editor loses extensionsUsed and instancing attributes

When I upload a .glb in the Editor, the resulting container asset loses the extensionsUsed metadata (EXT_mesh_gpu_instancing) and related attributes.

However, if I rename the same file (e.g., .glb.copy), upload it as a binary and load it manually, the instancing extension is preserved.


Container Asset:
extensionsUsed: undefined

Binary Asset:
extensionsUsed: ['EXT_mesh_gpu_instancing']

So the data is present in the GLB, but removed by the Editor’s conversion pipeline.


2. asset.getFileUrl() returns incorrect path in Launch mode (extra /api/)

Because of issue 1, I load the GLB manually from URL.
However, in Launch Preview, asset.getFileUrl() generates a URL that contains "/api/", which causes the load to fail. I have to manually slice it out:

// Workaround
const url = asset.getFileUrl().slice(5);

This only happens in Launch.
In bundled builds, the returned path is correct.


Code

initialize() {
    this.loadGlbContainer(this.binaryAsset, this.app);
    console.log('Container Asset:', this.containerAsset.resource.data.gltf);
}

loadGlbContainer(asset, app) {
    const assetUrl = asset.getFileUrl();

    // getFileUrl() contains extra "/api/" in Launch mode
    const url = assetUrl.slice(5);

    const sourceAsset = new pc.Asset(asset.name, 'container', { url });
    app.assets.add(sourceAsset);

    sourceAsset.once('load', () => {
        console.log('Binary Asset:', sourceAsset.resource.data.gltf);
        const gltfEntity = sourceAsset.resource.instantiateRenderEntity();
        this.entity.addChild(gltfEntity);
    });

    app.assets.load(sourceAsset);
}

Project Link: PlayCanvas | HTML5 Game Engine

  1. has a known issue/ticket for something similar Should asset.getFileUrl() return the full path? · Issue #2364 · playcanvas/engine · GitHub
  1. yes, when we import it, we convert it to an internal mesh representation, and then save it as glb, similarly to what we do with fbx files. This only preserves feature we support unfortunately, at least for now, and as you noticed, the extensions are removed (maybe not all, not entirely sure of the support there)

@slimbuck

Hi @yaustar @mvaligursky,
Thanks for the prompt reply and clarification.

In that case, I’m wondering whether preserving extensionsUsed during import is something that could be considered in the roadmap. Since there is already an official example that relies on EXT_mesh_gpu_instancing, it feels counter-intuitive that the workflow only works when bypassing the Editor.

I also noticed that the original .glb is still present in the assets folder as the type of source scene, which contains the extension data, but this asset is not included in the final build. If there were a way to tell the Editor to use the source GLB directly.

It’s definitely on a list of things we’d like to support, but it won’t be done in the near future unfortunately.

For now, the only option I’m aware of is what you already tried - renaming fhe file (extension) and manually loading that.

1 Like