External texture doesn't match GLB model without changing flipY

I export this model from Blender into GLB file with no material or texture.

uvtest_01

If I drop the GLB model into babylon sandbox and add external ambient texture it matches the shape:

uvtest_02

If I import the model into THREE and apply the same texture it doesn’t match:

uvtest_03

I can fix this by setting flipY = false to the texture but then if I want to measure UV from the texture in an image editor I need to count V axis from the top down, which makes things confusing.

Is it me doing something wrong here and is there a way to make this simpler w/o flipping in code and/or in the texture editor?

The UV coordinate convention used in glTF requires setting .flipY=false to textures using its UV maps. You’re not doing anything wrong here; this is also mentioned in the GLTFLoader documentation.

Either thinking of V ∈ [0, 1] as top-down, or else converting by v = 1 - v, are both fine options here I think.

Ok, thank you, out of curiosity, why set the top left corner and then have all these confusing flippings and extra code, wouldn’t it be better to set it normally like in opengl?

I’m afraid there’s not really a clear convention in graphics, e.g. even Unity and Unreal have different conventions for UV coordinates. WebGL requires “flipY=true” to get 0,0 = lower left, this isn’t a decision made by three.js. Not sure why glTF went with 0,0 = upper left, but it does enable GPU texture compression (e.g. KTX2 / Basis / ASTC / …) which are not compatible with “flipY=true”. Otherwise you’d need different UV conventions for compressed and uncompressed textures.

3 Likes