GLB exporter and PBR environment texture reflection missing

I have a mesh created with MeshBuilder and I am trying to attach a PBRMetallicRoughness material with a reflection texture. It’s not loading properly in GLTF, if at all it seems and I’m not sure why.
Here’s the playground test Babylon.js Playground

The code borrows heavily from someone else’s Babylon.js Playground

We’re trying to create a rounded rectangle plate that has a high reflectivity.
We used the example parking.env file from Babylon’s texture assets (copied into our S3 bucket to eliminate server load on Babylon’s end) as we needed a simple neutral colour reflection that would not impact the image users would upload while having enough details to create a nice reflection effect. The PBR texture is a simple square with half of it blue to allow metallicness through and half not. This is what allows the front of the print to show the user uploaded image with reflection and the back a grey matte color.

When we run the GLTF exporter on this output, we get what seems to be no reflection.
New users cannot post more than 2 links so I will post the link to the GLB file in a separate post.

I’m wondering what’s going on, is this a limitation of PBRMetallicRoughness in GLTF?

Side note: if the use of your texture assets in a commercial setting is not permitted, please let me know, we’ll happily retract them. It seems the project uses the Apache License and it permits it, but I’m asking nonetheless.

Here’s the output file
Load it in any GLB viewer like and you’ll see how different it is.

As I can see it’s working and reflects the environment

Did you try to change the environment texture in GLTFViewer?

Looks highly similar to me:


They are just not using the same environment ?

You are right that changing it inside the viewer affects it and results in your shown example.
But then the question becomes is this expected with GLTF? Am I doing anything wrong? I had followed the tutorial in the Babylon docs for PBR materials, setting the environmentTexture to an HDR CubeTexture. Pretty much everything is following standard practices, so I’m assuming this might be a GLTF exporter issue, but I can’t be sure.

Yea exactly, it’s just unclear yet if I’m not setting it properly or it’s a GLTF issue that I can’t resolve. My assumption is the PBR material gets the environment reflection set on it and that should be it. The playground example demonstrates the intended output as you saw as well.

I am still not sure I understand your issue.

Here you have an object that reflects the environment light setup in a scene. This environment is not part of GLTF so up to any viewer to chose what they want.

1 Like

Indeed as @sebavan, the environment is not part of the GLTF file

If you want the environment to affect your material you must assign it to the ReflectionTexture channel of your material

    var hdrTexture = new BABYLON.CubeTexture("textures/forest.env", scene);
    var material1 = new BABYLON.PBRMaterial("material1", scene);
    material1.reflectionTexture = hdrTexture;
    material1.roughness = 0
    material1.metallic = 1;
    polygon.material = material1

You can create a function to assign the reflectionTexture chanel after importing your model.

// Set Reflections
function setReflections() {
    scene.materials.forEach(function (material) {
        if ( != "skybox"
        && != "decalMaterial") {
            material.reflectionTexture = hdrTexture;
            material.reflectionTexture.level = 0.7;
            material.environmentIntensity = 1;

When you say the environment is not part of the GLTF file, do you mean the spec itself does not support it?

I ask because I implemented your suggestion and still cannot get a GLB file that shows the reflection texture.

    var material1 = new PBRMaterial(name, scene);
    var hdrTexture = new CubeTexture('', scene);
    material1.reflectionTexture = hdrTexture;   
    const texture = new Texture(texturePath, scene, { mimeType: "image/jpeg" });
    material1.albedoTexture = texture
    material1.reflectionTexture.level = 1;    
    material1.roughness = 0
    material1.metallic = 0.5;

The updated file I get is stored here
Place that in the GLTF viewer and you’ll see the same result in spite of the different material setup you proposed.

Hi @vic!

Here is another Playground

I recommend you to use the BabylonJS inspector.;

I’m importing the file that you provide me directly in the Playground.

BABYLON.SceneLoader.ImportMesh("", "", "sample_metal.glb", scene, function(newMeshes){
    var hdrTexture = new BABYLON.CubeTexture("textures/forest.env", scene);
    newMeshes[1].material.reflectionTexture = hdrTexture;
    console.log("Meshes: " + newMeshes);

When viewing the structure of your model you can access your “metal1” mesh.

In this case I access with

newMeshes[1].material.reflectionTexture = hdrTexture;

where do I assign the material

you can also use the function getMeshByName

var metal1 = scene.getMeshByName("metal1");

Access your Mesh to assign the texture to the reflectionTexture

I think the problem is in how you access your mesh

Consider that when using a file exported in glb format it carries a “root” structure

Therefore you have to search for the meshes to which you want to assign the reflection texture.

You can also iterate on all the imported meshes using a forEach function for example
Here it´s an example:

function setReflections() {
    scene.materials.forEach(function (material) {
        if ( != "skybox") {
            material.reflectionTexture = hdrTexture;
            material.reflectionTexture.level = 0.7;
            material.environmentIntensity = 1;
            material.disableLighting = false;

Hi Diego, I looked at the Playground you linked to. In the tools tab I clicked to export the GLB and loaded it in the GLTF viewer and that still wouldn’t get the reflection texture in. Did I miss a step?

Our use case is that we have a javascript application launched via a headless browser instance on a serverless app. It launches our Babylon script that renders a metal surface, the front of it comes from a user provided image, and we initiate a download script that includes using the Babylon GLTF transformer. It spits out a GLB file which we then will load into the user’s phone browser (for Android, if it’s an iPhone we’ll convert it to USDZ) so they can use AR to preview the print on their wall.
We wanted to use our own provided reflection texture to control the reflection they would see.
I’m not sure if explaining this helps; the idea is that our code is running via a JS app, but that Babylon app is not running on the user’s device.
It just runs remotely to create a file which we send back to the phone. We don’t have any control over how to render additional textures once that GLB file is created and sent back. If setting the reflection texture in the app, then running the GLTF transform and producing that GLB makes it impossible to preserve that reflection texture in, then I guess that’s a spec limitation we have to deal with.
Sorry if I’m not understanding what you are proposing!


In that case, keep in mind that the app responsible for generating the reflection would be the viewer you are using.

For example, testing iOS QuickLook you can clearly see that they use a neutral environment with several points of light, I suppose to create a reflection standard that adapts to the vast majority of situations.

I can’t think of another method, also if I come up with a solution I will be happy to help you

Thank you! It does sound like the issue is more with the spec and supporting HDR reflections baked in.
Appreciate the help!