Three.js: Add support for compressed versions of DataTexture2DArray and DataTexture3D.

Created on 16 Jun 2020  路  10Comments  路  Source: mrdoob/three.js

Would be nice to have a way for compressed 3D Textures and TextureArray for custom shaders.

Request is done after:
https://discourse.threejs.org/t/is-it-possible-to-have-a-texture-array-of-compressed-textures/16213

Browser
  • [x] All of them
  • [ ] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer
OS
  • [x] All of them
  • [ ] Windows
  • [ ] macOS
  • [ ] Linux
  • [ ] Android
  • [ ] iOS
Hardware Requirements (graphics card, VR Device, ...)
Enhancement

All 10 comments

@Mugen87 any suggestions how to start on this?

I'm afraid I've never worked with this use case so far so I'm not sure about this. But probably providing texture data for testing is a good start.

However, I'm not sure how such a provision would look like. Do existing texture compression formats support array of textures? Is it the task of a loader to provide an array of compressed textures? Or is this something the app has to compose?

the idea is to use compressed Textures for a Terrain splat map discussed with @gkjohnson in https://github.com/gkjohnson/threejs-sandbox/issues/9

using .basis texture compression with js Array on app Level

using .basis texture compression with js Array on app Level

How would it look like to compose multiple basis textures into a single Uint8Array? This would be required to make to call of WebGL2RenderingContext.compressedTexImage3D().

Here's a demonstration of loading an existing texture as a texture2darray in the webgl2 samples repo: link. You can see that the jpg they load in is already composed of the three separate images that would correspond to each texture layer.

In the example they write the image to a canvas and read the pixels back as uint8 array before uploading it but according to the docs for texImage3D it should work with a canvas or image element, as well, so it's not clear why they didn't upload the image directly.

I would think a Texture2DArray or CompressedTexture2DArray class would expect that the provided image is already composed of the images in the array like the example above and otherwise it should be up to the user to generate an image like that. Perhaps there could be a helper class like Texture2DArrayGenerator in the examples that can be used to generate a Texture2DArray object from a list of textures by drawing them to a canvas. Just a few thoughts!

this is how it works now with uncompressed raw image data

  const data = new Uint8Array(atlas.textures.length * 4 * 1024 * 1024);

          for (let t = 0; t < atlas.textures.length; t++) {
            const curTexture = atlas.textures[t];
            const curData = _GetImageData(curTexture.image);
            const offset = t * (4 * 1024 * 1024);

            data.set(curData.data, offset);
          }

          const diffuse = new THREE.DataTexture2DArray(data, 1024, 1024, atlas.textures.length);

_GetImageData i data is the raw image from a canvas

Right so you can generate the uint8 buffer on the fly using the read pixels approach and use a DataTexture2DArray for this use case. A Texture2DArray or CompressedTexture2DArray class would be more convenient and a bit faster considering reading pixel data from a canvas can be relatively slow, though.

lets see what @Mugen87 suggest.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

filharvey picture filharvey  路  3Comments

clawconduce picture clawconduce  路  3Comments

yqrashawn picture yqrashawn  路  3Comments

Horray picture Horray  路  3Comments