GLB with remote asset URLs

I’ve been experimenting with Tilt Brush on the Oculus Quest for rapid prototyping, it’s an insane amount of fun. An interesting issue is that the .glb files it exports use remote URLs for the texture assets.

The assets loads fine in the babylonjs sandbox, and all the textures get resolved.

But when I try to load the assets myself, it fails because the remote URL gets appended on to the URL where the .glb is being statically hosted, and 404s like this babylon.js:16 GET http://localhost:8080/assets/https://www.tiltbrush.com/shaders/brushes/Dots-6a1cf9f9-032c-45ec-9b1d-a6680bee30f7/Dots-6a1cf9f9-032c-45ec-9b1d-a6680bee30f7-v10.0-MainTex.png 404 (Not Found).

I used the same scene loading code as is used in the sandbox:

    BABYLON.SceneLoader.LoadAsync("assets/", "Untitled_2.glb", engine).then(scene => {
        
        scene.whenReadyAsync().then(() => {
            scene.createDefaultEnvironment();
            engine.runRenderLoop(function() {
                scene.render();
            });
        });
    }).catch(error => console.log(error));

Here is how the webpack-dev-server is hosting the glb file:

            {
                test: /\.(jpg|gif|env|glb|stl)$/i,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 8192,
                    },
                }, ],
            }

I can’t work out whether I need to set some other configuration on SceneLoader, or adjust the way webpack serves the glb file (or intercept and correct the URLs somehow?) Anyone have any thoughts on how to fix this?

Couple of interesting asides: it seems that having remote URLs for assets in .glb files isn’t valid, according to the gltf validator, it fails with NON_RELATIVE_URI errors. Remote URLs are vsalid in .gltf files though (I don’t know why this distinction exists between .glb and .gltf). But, both the babylonjs sandbox and Blender import the glb assets without complaint and resolve the textures.

pinging @bghgary

The sandbox works by chance. I should probably make it fail by default. The glTF spec has this to say about URIs:

glTF uses URIs to reference buffers and image resources. Clients must support at least these two URI types:

  • Data URIs

  • Relative URI paths — or path-noscheme as defined by RFC 3986, Section 4.2 — without scheme, authority, or parameters. Reserved characters must be percent-encoded, per RFC 3986, Section 2.2.

Implementation Note: Clients can optionally support additional URI components. For example http:// or file:// schemes, authorities/hostnames, absolute paths, and query or fragment parameters. Assets containing these additional URI components may be less portable.

I’m not sure why the glTF-Validator only flags the issue for GLBs. It should flag it for both.

OK that explains it. It’s a shame the gltf spec fudges it a little by saying “clients can optionally support”, as it leads to an inconsistent experience. For instance, the Blender glb import seems to handle remote URIs. I wonder why kronos couldn’t have explicitly specced it (say with a “remote URI” extension)?

I’ll double-check with the gltf file validation, I might have gotten mixed up.

I guess I’ll have to add a mesh cleanup step to the asset pipeline, probably using Blender to fetch the remote assets and then re-export.

I’m going to look at some of the other modelling tools on Oculus as well, such as Gravity Sketch, as Tilt Brush doesn’t produce particularly optimised assets.

All implementation notes are non-normative (i.e. they are not officially part of the spec), but I agree the messaging can lead to fragmentation.