Are KTX2 texture arrays supported in PlayCanvas?

I’ve got texture arrays working with JPG and PNG textures with the help of this code but when I use KTX2 textures I get an error. Are they supported in PlayCanvas? Is there any code examples to create one? I’ve run into the 16 texture unit limit using non-array textures hence the need for texture arrays.

It’s possible to create a KTX2 file with a number of layers for a texture array using toktx. I wonder if PlayCanvas supports it. The alternative is to create a texture atlas somehow.

I do not believe this is directly supported currently. I would suggest to use texture atlas - but that would mean creating the atlas ahead of time to be able to compress it to KTX2 format, not at load time.

Okay thanks, I’ll try that.

Texture atlases turned out to be problematic if you want repeating textures and mipmaps. You end up with lines which are due to sampling neighbouring tiles at the tile border on lower mipmap levels.

For anybody who’s trying to do something similar, I got KTX2 texture arrays working. You have to set the format property in the Texture to the format property of one of the KTX2 textures. Referring to code in this example:

const assets = {
    rockyTrail: new pc.Asset('rockyTrail', 'texture', { url: `${rootPath}/static/assets/textures/rocky_trail_diff_1k.ktx2` }),
    ...
};
...
const textureArrayOptions = {
    arrayLength: 4,
    format: assets.rockyTrail.resource.format,
    levels: [
        [
            assets.rockyTrail.resource.getSource(),
            assets.rockBoulder.resource.getSource(),
            assets.aerialRocks.resource.getSource(),
            assets.coastSand.resource.getSource()
        ]
    ]
    ...
};

If you want mipmap support (your KTX2 files need to contain mipmaps):

const levels = [];
for (let i = 0; i < assets.rockyTrail.resource.numLevels; i++) {
    levels.push([
        assets.rockyTrail.resource._levels[i],
        assets.rockBoulder.resource._levels[i],
        assets.aerialRocks.resource._levels[i],
        assets.coastSand.resource._levels[i]
    ]);
}
const textureArrayOptions = {
    arrayLength: 4,
    format: assets.rockyTrail.resource.format,
    mipmaps: true,
    numLevels: levels.length,
    levels,
    ...
};

All your textures in the array need to have the same format or you will get WebGL warnings.

2 Likes