typescriptcompressionwebglpixi.jsbasis

Pixi.js: BasisParser returns undefined from loading KTX2 file with custom extension


​ I get 'undefined' from the BasisParser that I use from Pixi itself, when loading a KTX2 file with a custom extension (through Assets.load):

import { TranscoderWorker } from '@pixi/basis'; 
import { loadKTX2 } from '../loaders/PixiLoadKTX2'; // Custom extension 
...

constructor() {
    Pixi.extensions.add(loadKTX2); TranscoderWorker.loadTranscoder(window.location.origin + '/basis_transcoder.js', window.location.origin + '/basis_transcoder.wasm'); 
}

public async create(filename: string): Promise<void> { 
    const texture = (await Assets.load(filename)) as Pixi.Texture; 
    const sprite = new Pixi.Sprite(texture); 

    ...
}

My extension code (see bottom) is based on the loadBasis extension from Pixi itself. I also use KTX-Parse to read the ktx2 file from which (I think) I use the basis data to transcode it to an usable pixi texture:

import { read } from 'ktx-parse'; 
...

const response = await settings.ADAPTER.fetch(url); 
const arrayBuffer = await response.arrayBuffer(); 
const ktxBuffer = concat([arrayBuffer]); 
const ktxContainer = read(ktxBuffer);  // KTX-Parse read function

let textures: Texture<Resource>[] = []; 
await new Promise<void>((res) => { 
    ktxContainer.levels.forEach(async (level, index) => { 
        const resources = await BasisParser.transcode(level.levelData); // Pixi basis transcoding
    const type: TYPES = BASIS_FORMAT_TO_TYPE[resources.basisFormat];
    const format: FORMATS = resources.basisFormat !== BASIS_FORMATS.cTFRGBA32 ? FORMATS.RGB : FORMATS.RGBA;

    textures = textures.concat(
        resources.map((resource) => {
            const base = new BaseTexture(resource, {
                mipmap: resource instanceof CompressedTextureResource && resource.levels > 1 ? MIPMAP_MODES.ON_MANUAL : MIPMAP_MODES.OFF,
                alphaMode: ALPHA_MODES.NO_PREMULTIPLIED_ALPHA,
                type,
                format,
                ...asset.data,
            });
            return createTexture(base, loader, url);
        })
    );

...

But I get 'undefined' in my 'resources' object when transcoding the basis data. When I look further into the BasisParser code in my node-modules and add some logs to debug, I see that it stops at the worker trying to transcodeAsync():

... 
await worker.initAsync(); 
// ---- Stops here 
const response = await worker.transcodeAsync(new Uint8Array(arrayBuffer), _BasisParser.defaultRGBAFormat.basisFormat, _BasisParser.defaultRGBFormat.basisFormat); 
// ---- 
const basisFormat = response.basisFormat; 
const imageArray = response.imageArray; 
const fallbackMode = basisFormat > 12;
...

The error:

tslib.es6.js:74 Uncaught (in promise) undefined

KTX2 Container is not (yet) implemented into pixi, that is why I'm searching for a way to get it loaded into a pixi sprite. To be sure you get enough information: I used KTXSoftware's toktx tool to create a KTX2 file from a png.
I tried these commands and have loaded them all in:

ETC1S
.\toktx.exe --t2 --encode etc1s --clevel 5 --qlevel 255 book.ktx2 book.png
ASTC
.\toktx.exe --t2 --encode uastc --uastc_quality 4 book.ktx2 book.png
UASTC
.\toktx.exe --t2 --encode astc --astc_blk_d 4x4 --astc_quality 100 book.ktx2 book.png

That's where I'm stuck at the moment. I don't know if I use the BasisParser or even the KTX2 data correctly? I use the latest Pixi V7.

KTX2 extension code: https://drive.google.com/file/d/1DUR5JBauEAqCp2WiGUeG359ew51KGzTE/view?usp=share_link

Thanks in advance.


Solution

  • I have implemented the KTX2 container in Pixi.js myself and I might ask for permission to contribute this to the project. But I first want to test some more and make sure the code is good enough. Proof that it worked.