Hi, I’ve implemented my own method to dispose a loaded model (THREE.Group
) form a .glb file.
To me it looks fine but I’d like someone to check if it’s the correct way to dispose resources or if I’m missing something?
unload(target:THREE.Object3D){
target.removeFromParent();
target.traverse((child:any) => {
// disposing materials
if (child.material && !child.material._isDisposed){
// disposing textures
for (const value of Object.values(child.material) as any[]){
if (!value) continue;
if (typeof value.dispose === "function" && !value._isDisposed){
value.dispose();
value._isDisposed = true;
}
}
child.material.dispose();
child.material._isDisposed = true;
}
// disposing geometries
if (child.geometry?.dispose && !child.geometry._isDisposed){
child.geometry.dispose();
child.geometry._isDisposed = true;
}
});
}
EDIT:
Here is the Garbage Collector friendly version
unload(target:THREE.Object3D){
target.removeFromParent();
target.traverse((child:any) => {
// disposing materials
if (child.material && !child.material._isDisposed){
// disposing textures
for (const [key, value] of Object.entries(child.material) as any[]){
if (!value) continue;
if (typeof value.dispose === "function" && !value._isDisposed){
value.dispose();
value._isDisposed = true;
child[key] = null;
}
}
child.material.dispose();
child.material._isDisposed = true;
child.material = null;
}
// disposing geometries
if (child.geometry?.dispose && !child.geometry._isDisposed){
child.geometry.dispose();
child.geometry._isDisposed = true;
child.geometry = null;
}
// disposing skinned mesh
if (child.skeleton?.boneTexture && !child.skeleton?.boneTexture._isDisposed){
child.skeleton.boneTexture.dispose();
child.skeleton.boneTexture._isDisposed = true;
child.skeleton.boneTexture = null;
}
requestAnimationFrame(() => child.children = null);
});
}