Can drei or R3F dispose resources with useGLTF()?
#2657
-
|
Right now I have a lot of non-declarative code to handle the cleanup on component unmounting of VRAM resources, as seemingly(?) gltf loading does not do so by itself. gltfjsx even inserts a For myMachine.dmgmori.com I call Material.dispose and Texture.dispose on each child texture of that material and BufferGeometry.dispose for Geometry and Skeleton.dispose on skeletons. Only that way can I exchange many 3D Machine Options and not blow through VRAM. Even worse actually, useGLTF() reallocates Geometry each time it mounts, so there is even a VRAM memory leak with So all this cleanup, I must do imperatively: Can't R3F / Drei / the gltfjsx structure handle that for me? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
|
@FrostKiwi short answer: no, neither R3F nor drei automatically deep-disposes GLTF GPU resources on unmount. you have to do it yourself. here's why and the correct pattern. why why why R3F's auto-disposal misses textures: the reconciler's the correct cleanup pattern: function Model({ url }) {
const gltf = useGLTF(url)
useEffect(() => {
return () => {
useGLTF.clear(url) // free JS cache
gltf.scene.traverse((child) => {
if (child.isMesh) {
child.geometry?.dispose()
const mats = Array.isArray(child.material)
? child.material : [child.material]
for (const mat of mats) {
for (const key of Object.keys(mat)) {
if (mat[key]?.isTexture) mat[key].dispose()
}
mat.dispose()
}
}
if (child.skeleton) child.skeleton.dispose()
})
}
}, [gltf, url])
return <primitive object={gltf.scene} dispose={null} />
}you need both
ref: R3F disposal docs | drei#1590 | drei#1911 | three.js dispose guide |
Beta Was this translation helpful? Give feedback.
@FrostKiwi short answer: no, neither R3F nor drei automatically deep-disposes GLTF GPU resources on unmount. you have to do it yourself. here's why and the correct pattern.
why
dispose={null}exists in gltfjsx output:useGLTFcaches loaded data viasuspend-react. if R3F auto-disposed meshes on unmount, remounting the same component would find corrupted GPU resources in the cache. so gltfjsx disables disposal to protect the cache.why
useGLTF.clear(url)isn't enough: it only removes the JS-side cache entry fromsuspend-react. it does NOT call.dispose()on any three.js objects. your geometries, textures, and materials stay in VRAM. (drei#1590 confirms this)why R3F's auto-disposal misses t…