Loading a large texture in the background

I’m currently working on a project that uses 3dPhotoDomes. It uses rather large panoramic images with a resolution of 12,000x6,000. Loading those in as textures works fine, both on mobile and desktop platforms, using the following method to load in the textures:

newTexture = new Texture(panoBackgroundFileURL, this.scene, false, false);

However, loading in the panoramas takes a long time on mobile especially. For this reason, I’m working on a system that first displays a smaller texture, and replaces it with a larger one once it is loaded. Loading the large texture the same way as above and using an onLoadObservable works, but causes a huge lag when the texture is loaded.

Looking for a solution I stumbled upon this suggestion by @Evgeni_Popov, using a worker to load the texture data in the background, creating an image bitmap and assigning it to a RawTexture. The code looks like this (sorry for lack of playground, but I think it wouldn’t work with the worker?).

const ImageLoaderWorker = new Worker('/image-loader.worker.js');

ImageLoaderWorker.postMessage(panoBackgroundFile.replace("_neu.jpg", "_neu_large.jpg"));

ImageLoaderWorker.addEventListener('message', event => {
    const imageData = event.data
    newTextureLarge = RawTexture.CreateRGBTexture(imageData.sprites, 12000, 6000, this.scene, false);
    console.log("Large image was loaded");
});

image-loader.worker.js:

self.addEventListener('message', async event => {
  const imageURL = event.data

  const response = await fetch(imageURL)
  const blob = await response.blob()

  Promise.all([
    createImageBitmap(blob)
  ]).then((sprites) => {
    self.postMessage({
      imageURL: imageURL,
      sprites: sprites[0],
    })
  });
})

This works… on desktop. However, it doesn’t work for most mobile browsers unfortunately, except firefox android. I’m getting the message:

WebGL: INVALID_VALUE: texImage2D: width or height out of range

And this is where I’m stuck. I’m a bit confused why this happens, as loading a regular texture from a URL works. But maybe this is a limitation specific to RawTextures? If so, does anyone know of a method for loading the image in the background without using a RawTexture?

No, there’s no limitation in RawTexture related to the texture dimensions. Given your error message, I would say that 12000x6000 texture sizes are not supported by your phone(s).

Note, however, that RawTexture does not rescale the data you provide: if the device only supports power-of-two (PoT) textures (like WebGL 1), then you will need to rescale the picture before creating the raw texture or use PoT pictures from the start.

If it’s just unsupported, why does loading the same texture using the URL instead of the worker work fine on the same devices though? There has to be a difference somewhere.
It’s not just a PoT issue unfortunately, using 8192*4096 textures I’m getting the same issue.

The standard code path for texture creation is also clamping the texture dimensions to the maximum supported size (engine.getCaps().maxTextureSize).

Can you check this value?

2 Likes

Indeed, this is giving me 4096 both on Chrome on Pixel 4a and Safari on iPad Pro. Interesting that firefox does support 16k on the Pixel, I guess in some instances they’re ahead in WebGL support. :slight_smile: In any case, thank you!