AO map added, but displayed on the wrong UV sets

See image below:

The second UV set is loaded correctly though, because it shows up after loading in the console:


The exact same model is loaded in Unity with the AO map on the 2nd set of UV’s, show that the shadow shows up indeed.

Do I need to set extra parameters in ThreeJs to apply the Light/AO map?

Please let me know!

Can you please share your model and textures in this thread?

Sure thing!
I added both GLTF and GLB. The example was the GLB file (303.5 KB)


Um, your glTF file is a bit confusing. Why does it not directly refer to the textures in the material definition? I’ve update the glTF and now it seems to work better. Is this your intended visual result?

TV_kast.gltf (4.7 KB)


Hi Mugen87,

This is an export form 3dsmax. Unfortunately thre GLTF exporter for 3ds max was not able to export the maps. So I ommited them, but I did have the 2nd UV channel.

Also, I’m trying to create some kind of editor which loads materials and textures on the fly, so that kept me from properly configuring the GLTF file. (I want to be able to change them later anyway ;)). I expected that setting the lightmap would use my second UV map, but it didn’t. What strikes me even more is that on a model with no 2nd UV channel, nothing happens. So this made me wonder if I’m setting up everything ok.

In your example I cant see the AO map having any effect, In my Unity example, you can see the shadow inside the case, that is the effect i’m after.

Maybe you can use the following example as a reference:

You might check if your object/material configuration does match with the one in the example.

The example is a bit minimalistic.
Just a json model is loaded, and not much configuring going on.

var loader = new THREE.ObjectLoader();
			loader.load( "models/json/lightmap/lightmap.json", function ( object ) {
				scene.add( object );
			} );\

Some digging around gave me the following parameters which are pre-set in the json model:

  "materials": [ ... ,
  "uuid": "56FF8500-53BD-4797-A1CD-4E22C54D186B",
  "type": "MeshPhongMaterial",
  "name": "floor",
  "emissive": 0,
  "specular": 1118481,
  "shininess": 100,
  "lightMap": "9F2CAC9D-AE10-4D5E-BE29-5105E807C99E",
  "lightMapIntensity": 0.75,
  "bumpMap": "19251D9F-B655-4799-A8F3-8BAF72AEA63A",
  "bumpScale": 2,
  "specularMap": "19251D9F-B655-4799-A8F3-8BAF72AEA63A",
  "depthFunc": 3,
  "depthTest": true,
  "depthWrite": true
},  ],

and for the textures:

"textures": [
  "uuid": "9F2CAC9D-AE10-4D5E-BE29-5105E807C99E",
  "name": "",
  "mapping": 300,
  "repeat": [ 1, 1 ],
  "offset": [ 0, 0 ],
  "center": [ 0, 0 ],
  "rotation": 0,
  "wrap": [ 1001, 1001 ],
  "format": 1023,
  "minFilter": 1008,
  "magFilter": 1006,
  "anisotropy": 4,
  "flipY": true,
  "image": "1FBD379E-9B4F-44B1-A2C7-E484904BF9D6"

I found that loading my model inside the ThreeJS Editor also created a strange result.
The first thing that I notices is that the UV’s are not screwed-up like in my ThreeJS instance. But whats up with the just black/white texture thing?

To visually recreate the problem that I’m experiencing i’d have to mirror my UV’s in 3ds max.

Exporting this created the right result in threejs instance.

Now the question is whether something goes wrong in the babylon exporter for 3ds max or when importing the glb?

I would try to import the original glb (without mirrored uvs) at sketchfab and see what happens. However, I can’t explain myself why mirroring the uvs solved your issue.

Sketchfab behaves as expected and displays my model correctly. I’m just going to upgrade to three r103

That fixed it for me,
I was using and I suspect the problem lies here. No time to dig into it atm.

@Mugen87, sorry to bother you though but thanks a lot for your help!

1 Like

I think glTF has a different texture transform than the three.js default. If you’re loading the texture separately try setting texture.flipY = false


Thanks for the suggestion, also a nice feature to be aware of!

Totally forgot that :upside_down_face:

I only remembered because I into this exact problem with an AO map yesterday :grin:

My initial solution was to flip the map in Photoshop, which is probably easier than mirroring uvs… But then I remembered the texture transform. It’s annoying, but I guess we’ll just have to keep it in mind when working with glTF.

There’s some additional detail in the Textures section here:

1 Like

There’s some additional detail in the Textures section here:

That’s great, I remembered reading this previously which is why I was able to solve this issue. However, it might be useful to make the information more prominent - somewhere near the top: “warning: if you are loading textures separately to your model, you will need to set texture.flipY = false. This is because the glTF UV space is the mirror of the three.js UV space.

Alternatively, and I’ve sure this was discussed previously somewhere, but couldn’t the GLTFLoader flip the UVs on load so that the UV spaces match? Or does that take too long?


While it does come up a lot, I’m not sure that a big scary warning will be helpful… the problem is probably that users assigning a texture to a material are (understandably) not thinking to look at the loader’s documentation at all…

… but couldn’t the GLTFLoader flip the UVs on load so that the UV spaces match? Or does that take too long?

So far GLTFLoader doesn’t do any per-vertex operations while parsing (except with morph targets), and can just reference directly into the binary .glb ArrayBuffer when creating BufferAttribute instances. flipping each UV would cause parsing time to be negatively affected by the number of vertices I think.


A good rule of thumb here IMHO is:

If it does any extra computation, the user probably wants to opt in