Hi!
This works for me:
package.json
:
{
"name": "bjs-ktx2",
"version": "1.0.0",
"scripts": {
"dev": "vite --open",
"build": "tsc && vite build",
"preview": "tsc && vite build && vite preview --host --open"
},
"typeRoots": [
"node_modules/@types",
"src/@types"
],
"devDependencies": {
"typescript": "^5.3.3",
"vite": "^5.2.7"
},
"dependencies": {
"@babylonjs/core": "^7.0.0",
"@babylonjs/inspector": "^7.0.0",
"@babylonjs/ktx2decoder": "^7.1.0",
"vite-plugin-arraybuffer": "^0.0.6",
"vite-plugin-wasm": "^3.3.0"
}
}
src/App.ts
:
import {
Scene,
Vector3,
HemisphericLight,
MeshBuilder,
StandardMaterial,
Color3,
Texture,
Engine,
ArcRotateCamera,
} from "@babylonjs/core";
import "@babylonjs/core/Debug/debugLayer";
import "@babylonjs/inspector";
import { KhronosTextureContainer2 } from "@babylonjs/core/Misc/khronosTextureContainer2";
import { AutoReleaseWorkerPool } from "@babylonjs/core/Misc/workerPool";
import { initializeWebWorker } from "@babylonjs/core/Misc/khronosTextureContainer2Worker";
import wasmMSCTranscoder from "@babylonjs/ktx2decoder/wasm/msc_basis_transcoder.wasm?arraybuffer";
import "@babylonjs/core/Materials/Textures/Loaders/ktxTextureLoader";
export class AppOne {
engine: Engine;
scene: Scene;
constructor(readonly canvas: HTMLCanvasElement) {
this.engine = new Engine(canvas);
window.addEventListener("resize", () => {
this.engine.resize();
});
this.scene = createScene(this.engine, this.canvas);
}
debug(debugOn: boolean = true) {
if (debugOn) {
this.scene.debugLayer.show({ overlay: true });
} else {
this.scene.debugLayer.hide();
}
}
run() {
this.debug(true);
this.engine.runRenderLoop(() => {
this.scene.render();
});
}
}
const createScene = function (engine: Engine, canvas: HTMLCanvasElement) {
const agentPool = new AutoReleaseWorkerPool(4, () => {
const worker = new Worker(new URL("./worker.js", import.meta.url), {
type: "module",
});
return initializeWebWorker(worker, {
wasmMSCTranscoder
});
});
const ktx2 = new KhronosTextureContainer2(engine, {
workerPool: agentPool,
});
const scene = new Scene(engine);
const camera = new ArcRotateCamera(
"camera1",
Math.PI / 3,
Math.PI / 4,
30,
new Vector3(0, 0, 0)
);
camera.setTarget(Vector3.Zero());
camera.attachControl(canvas, true);
const light = new HemisphericLight("light", new Vector3(0, 1, 0), scene);
light.intensity = 0.7;
const ground = MeshBuilder.CreateGround(
"ground",
{ width: 12, height: 12 },
scene
);
const groundMaterial = new StandardMaterial("groundMaterial", scene);
groundMaterial.diffuseColor = new Color3(0.5, 0.5, 0.5);
ground.material = groundMaterial;
groundMaterial.diffuseTexture = new Texture(
"https://cdn.dedalium.com/3d/dedalium/dedalium2_x256.ktx2",
scene
);
return scene;
};
vite.config.js
:
import { defineConfig } from 'vite';
import wasmPlugin from 'vite-plugin-wasm'
import arrayBuffer from 'vite-plugin-arraybuffer';
export default defineConfig(({ command, mode }) => {
return {
plugins: [wasmPlugin(), arrayBuffer()],
esbuild: {
supported: {
'top-level-await': true
},
},
optimizeDeps: {
esbuildOptions: {
supported: {
"top-level-await": true
},
},
},
};
});
src/worker.js
import * as KTX2Decoder from "@babylonjs/ktx2decoder";
import { workerFunction } from "@babylonjs/core/Misc/khronosTextureContainer2Worker";
import mscTranscoderJsModule from "@babylonjs/ktx2decoder/wasm/msc_basis_transcoder";
import { MSCTranscoder as jsMSCTranscoder } from "@babylonjs/ktx2decoder/Transcoders/mscTranscoder";
globalThis.KTX2DECODER = KTX2Decoder;
globalThis.MSC_TRANSCODER = undefined;
jsMSCTranscoder.JSModule = mscTranscoderJsModule;
workerFunction(KTX2Decoder);
