Load GLTF with .basis (not KTX2)

Hi everyone,

I am new to Babylon and currently working on loading the gltf file produced by our asset team.
And the problem I am facing is the gltf contains .basis file in the “images” node and the loader is not loading them correctly. I did test .ktx2 instead of .basis and it was loading correctly. Unfortunately we can’t use .ktx2 because it is still too big compare to .basis file (from our pipeline, the .ktx2 files are 3x larger than .basis files).

The gltf looks like this:

"images": [
        {
            "name": "camera_camera_Normal",
            "uri": "camera_camera_Normal.basis"
        },
        {
            "name": "camera_camera_BaseColor",
            "uri": "camera_camera_BaseColor.jpg"
        },
        {
            "name": "camera_tripod_BaseColor",
            "uri": "camera_tripod_BaseColor.jpg"
        },
        {
            "name": "camera_tripod_Normal",
            "uri": "camera_tripod_Normal.basis"
        },
        {
            "name": "camera_camera_Roughness",
            "uri": "camera_camera_Roughness.png"
        },
        {
            "name": "camera_tripod_Roughness",
            "uri": "camera_tripod_Roughness.png"
        }
    ],

Playground 1 with the png images - Babylon.js Playground
Playground 2 with the .basis compressed images - Babylon.js Playground

You can see the playground 1 is loading correctly with all the details but playground 2 isn’t.

The examples I can find are about loading the basis files directly but in our case, they are embedded in the gltf file under the “images” node.
Is there a way to load the .basis files correctly if they are in the gltf file?

Thank you for your help!

1 Like

Hello @evanwg and welcome to the forum! Maybe @bghgary has an idea

2 Likes

I’m a bit surprised by this. Both are containers that can store the BasisU compressed payload. The containers themselves have very little overhead. If the compression settings are the same between the two, they should have very similar sizes.

Using .basis in a glTF without an extension is not supported by the specification. You should avoid creating glTFs like this as it fragments the ecosystem. The right way to do this is to use .ktx2 as it should be able to do everything that .basis can do and more (as well as more tooling and better support). If you must use .basis, you should at least add a glTF extension similar to KHR_texture_basisu.

As for the code itself, you can add a glTF loader extension and follow the same pattern as what the KHR_texture_basisu loader extension does.

3 Likes

Thanks @bghgary!

Unfortunately we are bounded by what the other team can produce to us at the moment.
From what I understand, there are two things we need to do:

  1. Build our own extension and pick up .basis and then “assign” the texture to our 3D model
  2. Wrap the the custom extension like this (I think this might be optional if it is our internal custom extension and implement the loadTextureInfoAsync similar to this example: https://www.babylonjs-playground.com/#20XT9A#4):
    "extensionsUsed": [
        "CUSTOM_texture_basisu"
    ],
    "extensionsRequired": [
        "CUSTOM_texture_basisu"
    ],
    "textures": [
        {
            "extensions": {
                "CUSTOM_texture_basisu": {
                    "source": 0
                }
            }
        }
    ],
1 Like

Unfortunately we are bounded by what the other team can produce to us at the moment.

That’s unfortunate.

From what I understand, there are two things we need to do

After step 1, you should do something like Babylon.js/KHR_texture_basisu.ts at master · BabylonJS/Babylon.js (github.com).

1 Like