Load multiple images in texture without using texture atlas

Hi,

I’m trying to load small images as textures that are not pre-determined at compile time, therefore, can’t quite use texture atlas as a solution. For efficiency, I was thinking of passing a dynamic array of images, convert these into TEXTURE_2D_ARRAY, and use a single-pass shader rendering.

Now, CubeTextures have restrictions and others (DataTexture, DataArrayTexture) are lower-level (work with image data). I’m trying to avoid brute-force rendering using individual textures as that could become expensive.

I want to know if a pattern similar to twgl.js can be cleverly implemented in THREE.js; something like .createTexture() from images - relevant excerpt below:

    const slices = [
      "images/array/balloons.jpg",
      "images/array/biggrub.jpg",
      "images/array/curtain.jpg",
      "images/array/hamburger.jpg",
      "images/array/mascot.jpg",
      "images/array/meat.jpg",
      "images/array/orange-fruit.jpg",
      "images/array/scomp.jpg",
      "images/array/tif.jpg",
      "images/array/手拭.jpg",
      "images/array/竹輪.jpg",
      "images/array/肉寿司.jpg",
    ];

    const tex = twgl.createTexture(gl, {
      target: gl.TEXTURE_2D_ARRAY,
      src: slices,
    });

Open to better approaches or workarounds.

Thanks in advance!

One simple approach could be to construct the atlas dynamically via 2D canvas by drawing individual texture images into a large canvas and the create a texture out of it (see CanvasTexture). This would allow to change individual textures at run time. I’m not sure whether this would be OK for your use case.

2 Likes

Thanks!

Yes, this approach mostly works for local/ static assets in a browser - I did a few tests last year, however, it complained about tainted canvases for external image URIs (probably expected due to security reasons).

A constraint I forgot to mention is that I’m trying to do this in React Native environment (using expo-three/ expo-gl). Let me try doing something similar using react-native-canvas to see how far I get.

I’ve named it textureAtlas, but you can also run the code later at any time. It doesn’t have to be at the start of the app.

https://codepen.io/Spiri0/pen/qBzpqVa?editors=0010

Thank you! This gave me a good starting point. I had a few more constraints:

  • rendering all textures
  • different sizes for texture images
    With some padding in texture data and scaling in shader code, I’m able to render those textures correctly, all at once.

Next stop: finding a react native canvas solution to achieve this… :sweat_smile:

I may have to optimize for memory as well - saw the sample code had Uint8Arrays defined twice.