GLTFLoader: option to keep or prefer original texture or image name as name of loaded texture

Background

Name is defined in GLTF spec as Any top-level glTF object MAY have a name string property for this purpose. These property values are not guaranteed to be unique as they are intended to contain values created when the asset was authored.

In some exported GLTF files, name can exist in both textures and images like:

   "textures": [
        {
            "name": "MyTextureName",
            "sampler": 0,
            "source": 0
        }
    ],
    "images": [
        {
            "name": "MyImageName",
            "uri": "data:image/png;base64,..."
        }
    ],

When using Babylon.js internal GLTFLoader, the name of loaded texture is set like this:

And name of GLTF’s texture or image is lost.

Playground Example

The file is silghtly modified from BoxTextured.gltf from glTF-Sample-Models.

Proposal

Add an option, statically or instance-bound, to make GLTFLoader prefer to use original texture or image name as name of loaded texture whenever possible, which could has false by default to keep backwards compatibility with existing code.

cc @bghgary

We need to consider that a glTF texture is not a Babylon texture.

Here is how the mapping goes:

  • glTF textureInfo → Babylon.js Texture
  • glTF texture → Babylon.js InternalTexture
  • glTF image → no equivalent

glTF textureInfo is not a top-level glTF object with a name. Multiple glTF textureInfo can point to the same glTF texture. Multiple glTF texture can point to the same glTF image.

Maybe storing a name on the Babylon.js InternalTexture would work?

1 Like

@bghgary I’m facing a similar topic and so I’m very interested in the state of this feature request.
Is the state visible somewhere in the forum entry?
If not, could you please give me a personal update? :slight_smile:

Would be great if the glTF image (data or pointer) would be somehow available.

This thread died after my post, so we haven’t done anything with this. If we want this done, it would be good to file a feature request on GitHub and we will see if we can sneak some time to do it.

I don’t know what you mean by data or pointer. If you want to access the glTF JSON object, this is available with the onParsedObservable.

I should be more exact :slight_smile:
I meant “glTF image available at Texture object”, as currently there is no equivalent.

@bghgary thx a lot for the response.
Seems like onParsedObservable is all I need anyway.
I saw that the gltf texture path is stored in the Babylon.js textures _internalMetadata, so I should be able to reconstruct the original file name from there.

1 Like

@bghgary reactivating this topic, as it got more important on our side as well.

For some context, we run a platform at Combeenation, that allows the user to upload 3d models (glb or .babylon) and extract the materials for some little tweaking.
The user is also able to upload image files and link that directly into the dedicated texture channel.
Per default the system expects the user to upload an image file with the exact name of the texture, but as this thread says, it would be better if the original file name would be linked.

Here is an example

  • actual file name: “plastic_bc” => this file was uploaded by the user
  • linked file name: “cup_lp_Plastic_BaseColor” => default texture name with some extra steps (Prefixing, Character Validation,…)
    …doesn’t match, so the user has to assign the uploaded file manually

The onParsedObservable solution as mentioned above has the big downside, that it only works for glbs. When uploading a .babylon file we have no chance to get to the original gltf image file name anymore.
Also it’s a bit clunky to reconstruct the image link afterwards, while it would be available in the gltf parser code right away.

So is there a chance to just add the original image file name in the textures _internalMetadata?
When serializing the scene, it should be stored in the .babylon file and we can access it on our platform.
As far as I have seen there is a very good place in the _createTextureAsync function, where you have access to the babylon runtime texture and the parsed image data alike.

I am very willing to contribute this code on my own, I’d just need to know how the structure in the _internalMetadata.gltf should look like for that textures.

Looking forward to your response!

1 Like

I’m having a hard time understanding what you are describing because of the overloaded terms.

As I mentioned earlier, this is the mapping:

Which objects are in question in your scenario?

I think you might be after the url of the loaded image which is already stored in the InternalTexture object. Here is an example: Babylon.js Playground. Does this do what you want?

If you need the name of the glTF texture object stored somewhere (which is currently ignored by the loader), then I would suggest we add a property to InternalTexture to store this name so that it is a 1-to-1 mapping to glTF.

Hi @bghgary,

I am definitely after the glTF image, sorry for the confusion.

I think your scenario is fine for glTF imports, as the file name is just the last part of the URL, but it won’t work for glb as far as I have seen, as the url is data:**glbPath**#image**n** in this case.


…which makes sense, since the texture image is baked in the glb file and there is no dedicated url for the texture image.
PG example for glb

Your suggestion concerning 1-to-1 mapping in the InternalTexture sounds good to me.

I think it will be really useful is some cases.

I agree with this

I tried to implement this, but there was a problem. glTF texture is not an exact 1:1 mapping to Babylon.js InternalTexture like I originally thought.

glTF texture → sampler + image source
glTF textureInfo → glTF texture + texture coordinate set index

Babylon.js InternalTexture → image source
Babylon.js Texture → InternalTexture + sampler info + texture coordinate info

If we try to store the glTF texture name in Babylon.js InternalTexture, there can be conflicts. For example, two glTF textures pointing to the same image source. I’ll have to think about this more. Suggestions welcome. :slight_smile:

1 Like

Hi @bghgary,

you’re definitely right, multiple glTF textures and therefore Babylon.js InternalTextures can point to the same glTF image, but I don’t really see a problem with this.

Let’s say glTF texture 1 and 2 both reference an image “imageFile.jpg”.
I’d imagine that there is a property like “imageSource” in the Babylon.js InternalTexture object.
In this case Babylon.js InternalTextures 1 and 2 will both have set “imageFile.jpg” as “imageSource”.
In my use case I can link both texture channels to the same Image File, called “imageFile.jpg”.

Maybe I am overseeing something here? :thinking:

I don’t think there’s any conflict. If two gltf textures point to one, they just need to share the same texture data. Whether adjusting the UV offset or scale, they should be universal

1 Like

The conflict is the name not the properties.

I think maybe we can add a flag to the loader to load the names on the Babylon.js texture. If two glTF textureInfo points to same glTF texture, then the two Babylon.js textures will have the same name. It will be ambiguous, but the documentation for this flag can indicate that this may happen.

1 Like