Jump to content

Getting black Pixi sprite from loading KTX2 file [TypeScript]


Deoxyz
 Share

Recommended Posts

Hi

I'm getting black textures when I'm trying to load KTX2 files using loaders.gl and use the UInt8Array to load a texture with from or fromBuffer and create a Pixi sprite with it.
It doesn't matter if I make a BaseTexture first or not.

pixiKTX2WeBGL.thumb.png.4f73dabdaad8ee37799315b4c4ac5047.png

Code with BasisLoader & Texture.fromBuffer:

import { BasisLoader } from '@loaders.gl/textures';
import { load } from '@loaders.gl/core';
import * as Pixi from 'pixi.js';

...

const loadOptions = {
     format: 'auto',
     containerFormat: 'ktx2',
     module: 'encoder',
};
const resources = await load(filename, BasisLoader, loadOptions);
const textureData = resources[0][0];
const texture = Pixi.Texture.fromBuffer(textureData.data, textureData.width, textureData.height);
const sprite = new Pixi.Sprite(texture);

Code with CompressedTextureLoader & Texture.from with BaseTexture:

import { CompressedTextureLoader } from '@loaders.gl/textures';
import { load } from '@loaders.gl/core';
import * as Pixi from 'pixi.js';

...

const loadOptions = {
	useBasis: true,
};
const resources = await load(filename, CompressedTextureLoader, loadOptions);
const textureData = resources[0];

const baseTexture = new Pixi.BaseTexture(
  new BufferResource(textureData.data, {
    width: textureData.width,
    height: textureData.height,
  })
);
const texture = Pixi.Texture.from(baseTexture);
const sprite = new Pixi.Sprite(texture);

Log output:

pixiTextureKTX2Log.thumb.png.04594df009621b5021707ec3600c0ca6.png

 

I also tried Pixi's CompressedTextureResource:

const baseTexture = new Pixi.BaseTexture(
	new Pixi.CompressedTextureResource(textureData.data, {
		format: textureData.format,
		width: textureData.width,
		height: textureData.height,
	})
);

But got this:

compressedPixiTextureKTX2.thumb.png.2a8fc85b976295f4ef2fa844653e3d76.png

 

KTX2 Container is not (yet) implemented into pixi, that is why I had to try other ways to get it loaded into a pixi sprite. I'm not fully understanding all of the compression stuff yet, so I'm probably forgetting something.

To be sure you get enough information: I used KTXSoftware's toktx tool to create a KTX2 file from a png: https://github.com/KhronosGroup/KTX-Software 
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

 

So if someone could point me in the right direction, that would be awesome.
Thanks in advance!

Link to comment
Share on other sites

  • 2 weeks later...
2 hours ago, TobiasW said:

Did you ever solve this? I've been seeing the same behaviour with version 6.

I'm still figuring things out. Trying some different approaches, but I will post my solution here once I've found it.

Link to comment
Share on other sites

On 3/2/2023 at 9:05 AM, Deoxyz said:

I'm still figuring things out. Trying some different approaches, but I will post my solution here once I've found it.

So I think I'm a step further, but I get undefined from the BasisParser that I use from Pixi itself.
What did I do? I created and added an extension to load KTX2 files using 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);
  	...
    
}

I added my extension code in the attachments, which 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 'resources' 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

That's where I'm stuck at the moment.
I don't know if I use the BasisParser or even the KTX2 data correctly? Or that it could even work this way in the first place?

I don't know if someone from Pixi that is on this forum sees what I'm doing wrong?
I have a feeling that I'm very very close 😁

Anyway, thanks in advance.

PixiLoadKTX2.ts

Link to comment
Share on other sites

  • Deoxyz changed the title to Getting black Pixi sprite from loading KTX2 file [TypeScript]

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...