1- import {
2- CompressedTexture ,
3- Texture ,
4- TextureLoader ,
5- WebGLRenderer ,
6- } from "three" ;
1+ import { CompressedTexture , Texture , TextureLoader } from "three" ;
2+ import { WebGLExtensions } from "three/src/renderers/webgl/WebGLExtensions" ;
73import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader" ;
8- import { useThree } from "@react-three/fiber" ;
94import { useGLTF } from "@react-three/drei" ;
105import { suspend , preload , clear } from "suspend-react" ;
116import { getFallbackTexture } from "./fallback" ;
@@ -16,17 +11,46 @@ const KTX_CDN = "https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/";
1611const textureLoader = new TextureLoader ( ) ;
1712let ktx2loader : KTX2Loader | undefined ;
1813
19- const setupKtx2 = ( gl : WebGLRenderer ) => {
14+ // it's inconvenient to have to produce a gl object to check for ktx2 support, especially when it comes to the cache keys
15+ // solution is to create a skeleton object that provides the minimum requirements to check for ktx support, defined below
16+ // https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/KTX2Loader.js#L113-L135
17+ type PotentialCanvas = WebGLRenderingContext | WebGL2RenderingContext | null ;
18+ type KTXSupportCheck = {
19+ capabilities : { isWebGL2 : boolean } ;
20+ extensions : WebGLExtensions ;
21+ } ;
22+ const setupKtx2 = ( ) => {
2023 if ( ktx2loader ) return ;
24+
2125 ktx2loader = new KTX2Loader ( ) ;
2226 ktx2loader . setTranscoderPath ( KTX_CDN ) ;
23- ktx2loader . detectSupport ( gl ) ;
27+
28+ let supportsWebgl2 : boolean ;
29+ const el = document . createElement ( "canvas" ) ;
30+ let gl : PotentialCanvas = el . getContext ( "webgl2" ) ;
31+ if ( gl ) {
32+ supportsWebgl2 = true ;
33+ } else {
34+ gl = el . getContext ( "webgl" ) ;
35+ supportsWebgl2 = false ;
36+ }
37+ if ( ! gl ) {
38+ throw new Error ( "No WebGL support" ) ;
39+ }
40+ el . remove ( ) ;
41+ const minimumGL : KTXSupportCheck = {
42+ extensions : new WebGLExtensions ( gl ) ,
43+ capabilities : { isWebGL2 : supportsWebgl2 } ,
44+ } ;
45+
46+ // @ts -ignore
47+ ktx2loader . detectSupport ( minimumGL ) ;
2448} ;
2549
2650function loadimage ( ) {
27- return function ( url : string , gl : WebGLRenderer ) {
51+ return function ( url : string ) {
2852 const IS_KTX2 = url . toLowerCase ( ) . endsWith ( "ktx2" ) ;
29- setupKtx2 ( gl ) ;
53+ setupKtx2 ( ) ;
3054 const loader = IS_KTX2 ? ktx2loader ! : textureLoader ;
3155 return new Promise < Texture | CompressedTexture > ( ( res ) =>
3256 loader . load ( url , res , undefined , ( error ) => {
@@ -45,16 +69,15 @@ function loadimage() {
4569 * @param url
4670 */
4771export function useImage ( url : string ) : Texture {
48- const gl = useThree ( ( st ) => st . gl ) ;
49- return suspend ( loadimage ( ) , [ url , gl ] ) ;
72+ return suspend ( loadimage ( ) , [ url ] ) ;
5073}
5174
52- useImage . preload = function ( url : string , gl : WebGLRenderer ) {
53- return preload ( loadimage ( ) , [ url , gl ] ) ;
75+ useImage . preload = function ( url : string ) {
76+ return preload ( loadimage ( ) , [ url ] ) ;
5477} ;
5578
56- useImage . clear = function ( url : string , gl : WebGLRenderer ) {
57- return clear ( [ url , gl ] ) ;
79+ useImage . clear = function ( url : string ) {
80+ return clear ( [ url ] ) ;
5881} ;
5982
6083/**
@@ -64,22 +87,19 @@ useImage.clear = function (url: string, gl: WebGLRenderer) {
6487 * @param url
6588 */
6689export function useModel ( url : string ) : GLTF {
67- const gl = useThree ( ( st ) => st . gl ) ;
6890 return useGLTF ( url , true , true , ( loader ) => {
69- setupKtx2 ( gl ) ;
91+ setupKtx2 ( ) ;
7092 loader . setKTX2Loader ( ktx2loader ! ) ;
7193 } ) ;
7294}
7395
74- useModel . preload = function ( url : string , gl : WebGLRenderer ) {
96+ useModel . preload = function ( url : string ) {
7597 return useGLTF . preload ( url , true , true , ( loader ) => {
76- setupKtx2 ( gl ) ;
98+ setupKtx2 ( ) ;
7799 loader . setKTX2Loader ( ktx2loader ! ) ;
78100 } ) ;
79101} ;
80102
81103useModel . clear = function ( url : string ) {
82104 return useGLTF . clear ( [ url ] ) ;
83105} ;
84-
85- console . log ( useModel ) ;
0 commit comments