Fiber Auto disposes, with the exception of primitive. Primitive points to a foreign object that you or something else control, it can’t just go and destroy it. You can dispose yourself if you control the object yourself.
On top of that all loaders are cached, two useGLTF with the same url will return the same object data, it won’t load or parse twice, but after unmount the cached data is still there.
You have access to the cache and can clear it but usually that’s a rare use case. Most webgl projects will load all assets up front and do not mount or change them runtime, because mounting in threejs is very expensive. Could you describe what you want to do?
Thank you for your reply, I do this because we have the feature to switch between 2D/3D styles. Maybe I can refresh the page, but need to keep all the use state.
i would also suggest using gltfjsx --transform to compress models and textures. or better yet use ktx2. if you’re dealing with such an amount of data that you need to clear cache that probably points to a lot of excess data.
I have questions, my understanding is that gltfjsx is for specific models, predefined. But my models is hosting on the server, I can only get their urls and names, then I use useGLTF or useLoader to load them. In my case, does gltfjsx works?
Thank you again, I will try this way. According to the official documentation Loading Models, models are always hosted in primitive, do I have the other way to add a model with auto disposal?
<mesh /> // <---- this gets removed and disposed of on unmount
<group /> // <---- this gets removed and disposed of on unmount
<orbitControls /> // <---- this gets removed and disposed of on unmount
<foo /> // <---- this gets removed and disposed of on unmount
otherwise you have useEffect, cache clear and a special dispose that traverses the object since dispose in threejs is not really that easy to do by hand, i believe scene.dispose() will do nothing even.
keep in mind that by doing so if you mount the model again it will have to parse again, it would be massively wasteful. i would only recommend that when things don’t go onto the screen ever.
ps, i would also use gltfjsx instead of a primitive. looks weird to me to use a primitive object={scene}, which already has children, and then overwrite children like that. it probably works but seems sketchy. with gltfjsx you can also omit the “dispose={null}” that it attaches on the root mesh, if you remove it it will dispose the whole scene automatically since none of it is a primitive. you still need to do the cache clear because the model is essentially destroyed on unmount.
@drcmda do would you know if useGLTF automatically uses useMemo internally in order to memoize geometries and materials preventing regeneration when rerendering or would that be handled manually?
Yes I understood that from the thread above and fwiu suspense is to wait for the model to load, I guess my question is slightly different from the OP’s, does useGLTF behave in the same way that useMemo for the geometries and materials part of the file in the same way as…
const geo = useMemo(() => {
return new THREE.BufferGeometry()
}
so that the geometry and materials associated aren’t recreated ever render eg when the model is hovered for instance?
useMemo memoizes at the component level, two components memoizing a thing will execute twice. suspense is global memoization. the geometries and materials that useGLTF returns are the same where ever it’s called, given that it’s being called with the same key (the url). they aren’t re-created, they are always re-used.