Failed to load ktx2 model

Hey there

I am currently developing a 3D website for my portfolio and i noticed that my 3d model loads slow.
So i started to look for the solution and i’ve bumped into Wawa Sensei’s video about ktx2.
I’ve transformed my glb to ktx2 and tried to do it as shown on video.
Link to Wawa Sensei’s video

Here is the full code. But, originally, transcoder path that is being set by function SetTranscoderPath() had a link “https://cdn.jsdelivr.net/gh/pmndrs/drei-assets/basis/” but
if you paste it and look for it then it leads you to message: Package size exceeded the configured limit of 50 MB. Try drei-assets/basis at master · pmndrs/drei-assets · GitHub instead.

So i used this link instead

import { useScroll, useGLTF, GradientTexture, Loader } from "@react-three/drei";
import { useFrame, useThree } from "@react-three/fiber";
import { folder, useControls } from "leva";
import gsap from "gsap";
import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader";

export function Axe(props) {
 const gl = useThree((state) => state.gl);
 const { nodes, materials } = useGLTF(
  "/transformed/free_axe_sylvaxe_ktx.glb",
   undefined,
   undefined,
   (loader) => {
     const ktx2loader = new KTX2Loader();
     ktx2loader.setTranscoderPath(
       "https://github.com/pmndrs/drei-assets/tree/master/basis/"
     );
     ktx2loader.detectSupport(gl);
     loader.setKTX2Loader = ktx2loader;
     loader.setKTX2Loader(ktx2loader);
   }
 );

  const axe = useRef();
  const axeScale = useRef();
  const scroll = useScroll();
  const tl = useRef();
  useFrame((state, delta) => {
    tl.current.seek(scroll.offset * tl.current.duration());
  });
  useLayoutEffect(() => {
    tl.current = gsap.timeline({
      defaults: { duration: 0.3, ease: "power1.inOut" },
    });

    tl.current
      .to(axe.current.position, { x: 4 }, 0.1)
      .to(axe.current.position, { y: 0 }, 0.1)
      .to(axe.current.position, { z: 1.5 }, 0.1)
      .to(axe.current.rotation, { x: -0.2 }, 0.1)
      .to(axe.current.rotation, { y: -4.3 }, 0.1)
      .to(axe.current.rotation, { z: 0 }, 0.1)
      .to(axeScale.current.scale, { x: 0.0115, y: 0.0115, z: 0.0115 }, 0.1)
      .to(axe.current.position, { x: -4.7 }, 0.4)
      .to(axe.current.position, { y: -0.16 }, 0.4)
      .to(axe.current.position, { z: 1.44 }, 0.4)
      .to(axe.current.rotation, { x: -0.2 }, 0.4)
      .to(axe.current.rotation, { y: -1.97 }, 0.4)
      .to(axe.current.rotation, { z: 0 }, 0.4)
      .to(axeScale.current.scale, { x: 0.01, y: 0.01, z: 0.01 }, 0.4)

      .to(axe.current.position, { x: -0.13 }, 0.7)
      .to(axe.current.position, { y: -1.09 }, 0.7)
      .to(axe.current.position, { z: 0.5 }, 0.7)
      .to(axe.current.rotation, { x: -0.57 }, 0.7)
      .to(axe.current.rotation, { y: -3.11 }, 0.7)
      .to(axe.current.rotation, { z: -1.62 }, 0.7)
      .to(axeScale.current.scale, { x: 0.01, y: 0.01, z: 0.01 }, 0.7);
  }, []);
  return (
    <group
      {...props}
      dispose={null}
      position={[-1.23, 0, 0]}
      rotation={[-0.2, -2.49, 0]}
      ref={axe}
    >
      <group>
        <group rotation={[-Math.PI, 0, 0]} scale={0.01} ref={axeScale}>
          <mesh
            geometry={nodes.Sylvaxe_Sylvaxe_0.geometry}
            material={materials.Sylvaxe}
            rotation={[Math.PI / 2, 0, 0]}
          />
        </group>
      </group>
    </group>
  );
}

useGLTF.preload("/transformed/free_axe_sylvaxe_ktx.glb");

But i end up seeing this error in the console:
Uncaught Error: Could not load /transformed/free_axe_sylvaxe_ktx.glb: THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures

And also message:
THREE.WebGLRenderer: Context Lost.

P.S. i transformed glb to jsx using gltfjsx
Link

Does anybody know what to do in this situation?
Thank you

Already tried it… Didn’t help, same problem.
Btw, i forgot to delete line(was trying to fix it, didn’t help either):
loader.setKTX2Loader = ktx2loader;

So know main part where i load the model looks like this:

const gl = useThree((state) => state.gl);
 const { nodes, materials } = useGLTF(
  "/transformed/free_axe_sylvaxe_ktx.glb",
   undefined,
   undefined,
   (loader) => {
     const ktx2loader = new KTX2Loader();
     ktx2loader.setTranscoderPath(
       "https://github.com/pmndrs/drei-assets/tree/master/basis/"
     );
     ktx2loader.detectSupport(gl);
     loader.setKTX2Loader(this.ktx2loader);
   }
 );

The post shared may be confusing if you’re not building a class with internal properties and methods, your already declaring ktx2loader as a constant within the confines of your primary loader function… Try this…

loader.setKTX2Loader(ktx2loader) 

Instead of “this.”, which seems to be irrelevant in your case…

Thank you for trying to help me!
I forgot to delete “this.” in the code, sorry

  const gl = useThree((state) => state.gl);
 const { nodes, materials } = useGLTF(
  "/transformed/free_axe_sylvaxe_ktx.glb",
   undefined,
   undefined,
   (loader) => {
     const ktx2loader = new KTX2Loader();
     ktx2loader.setTranscoderPath(
       "https://github.com/pmndrs/drei-assets/tree/master/basis/"
     );
     ktx2loader.detectSupport(gl);
     loader.setKTX2Loader(ktx2loader);
   }
 );

Still the same error

OK, that seems like it should work :thinking:

Did you already reference the usage…

import { useGLTF } from '@react-three/drei'
import { REVISION } from 'three'
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader'
import { useThree } from '@react-three/fiber'

 const { gl } = useThree()

const { scene } = useGLTF('/myScene-transformed.glb', false, false, (loader) => {
    const THREE_PATH = `https://unpkg.com/three@0.${REVISION}.x`
    const ktx2Loader = new KTX2Loader().setTranscoderPath(`${THREE_PATH}/examples/jsm/libs/basis/`)
    loader.setKTX2Loader(ktx2Loader.detectSupport(gl))
})

taken from here… How to use KTX2Loader with useGLTF, and without use useKTX2() which seems to need explicit textures URIs · pmndrs/drei · Discussion #1335 · GitHub