Skip to content

Commit

Permalink
fix useTexture callback
Browse files Browse the repository at this point in the history
Co-authored-by: Johannes Wüller <[email protected]>
  • Loading branch information
clementroche and jwueller committed Nov 7, 2024
1 parent bc966ec commit 6ca0358
Showing 1 changed file with 11 additions and 19 deletions.
30 changes: 11 additions & 19 deletions src/core/Texture.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react'
import { Texture as _Texture, TextureLoader } from 'three'
import { useLoader, useThree } from '@react-three/fiber'
import { useLayoutEffect, useEffect, useMemo } from 'react'
import { useEffect, useLayoutEffect, useMemo } from 'react'

export const IsObject = (url: unknown): url is Record<string, string> =>
url === Object(url) && !Array.isArray(url) && typeof url !== 'function'
Expand All @@ -20,31 +19,20 @@ export function useTexture<Url extends string[] | string | Record<string, string
onLoad?: (texture: MappedTextureType<Url>) => void
): MappedTextureType<Url> {
const gl = useThree((state) => state.gl)
const textures = useLoader(TextureLoader, IsObject(input) ? Object.values(input) : input) as MappedTextureType<Url>

useLayoutEffect(() => {
onLoad?.(textures)
}, [onLoad])
const textures = useLoader(TextureLoader, IsObject(input) ? Object.values(input) : input)

// https://github.com/mrdoob/three.js/issues/22696
// Upload the texture to the GPU immediately instead of waiting for the first render
// NOTE: only available for WebGLRenderer
useEffect(() => {
if ('initTexture' in gl) {
let textureArray: _Texture[] = []
if (Array.isArray(textures)) {
textureArray = textures
} else if (textures instanceof _Texture) {
textureArray = [textures]
} else if (IsObject(textures)) {
textureArray = Object.values(textures)
}

textureArray.forEach((texture) => {
if (texture instanceof _Texture) {
for (const texture of textures) {
gl.initTexture(texture)
}
})
} else {
gl.initTexture(textures)
}
}
}, [gl, textures])

Expand All @@ -55,10 +43,14 @@ export function useTexture<Url extends string[] | string | Record<string, string
for (const key in input) keyed[key] = textures[i++]
return keyed
} else {
return textures
return textures as MappedTextureType<Url>
}
}, [input, textures])

useLayoutEffect(() => {
onLoad?.(mappedTextures)
}, [mappedTextures])

return mappedTextures
}

Expand Down

0 comments on commit 6ca0358

Please sign in to comment.