Textures in gLTF sometimes display black, but only on iOS

We’ve had this black textures issue bugging our app on iOS since version 14 and it does seem indeed that the issue is now appearing much more frequently on iOS 15.

I was tasked to find the root cause of the issue and I pinpointed it to image bitmaps. On iOS 14 and 15 all textures that use image bitmaps as the image are sometimes displayed as fully black, and this happens very often on iOS 15.

So a quick fix is to just not use image bitmaps on iOS. Since you can’t disable the usage of image bitmaps in GLTFLoader via any options (three.js/GLTFLoader.js at 00a692864f541a3ec194d266e220efd597eb28fa · mrdoob/three.js · GitHub), I used this (a bit hacky) little piece of code in our app, which effectively disables the usage of image bitmaps on iOS:

const IS_IOS =
  /^(iPad|iPhone|iPod)/.test(window.navigator.platform) ||
  (/^Mac/.test(window.navigator.platform) && window.navigator.maxTouchPoints > 1);
if (IS_IOS) {
  window.createImageBitmap = undefined;
}

And finally to prove my point that the issue is indeed in image bitmaps, here’s a test scene that has 15 planes with 2048x2048 textures.

On my iPhone 7 (iOS 15.1) the ImageLoader version never shows any black textures, but the ImageBitmapLoader version does render some (4-6 of them) of the textures black 90% of the time.

This is definitely something that should be fixed by Apple and a webkit bug report ought to be submitted, but in the mean time I also wonder if this is something that should be handled inside GLTFLoader? What do you think @donmccurdy?

3 Likes