-
-
Notifications
You must be signed in to change notification settings - Fork 35.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scene environment and scene background are leaking after deep clean #30516
Comments
For performance reasons the renderer keeps a few references to internal materials and geometries like the skybox mesh. As long as the memory is not keep growing we do not consider this as a bug or misbehavior. Maybe we should document this in the FAQ section for a better understanding. Meaning even if you perform a deep clean, you potentially see a few entries in |
I see your point. For the scenario where the scene is cleared and repopulated multiple times, the texture related to the usage of One would end up with as many textures hanging around as For this issue I managed to make a hack by overriding THREE.PMREMGenerator.prototype._compileMaterial = (function () {
const oldCompileMaterial = THREE.PMREMGenerator.prototype._compileMaterial;
return function (this: THREE.PMREMGenerator, material: THREE.Material): void {
oldCompileMaterial.call(this, material);
this._renderer._pmremGenerators = this._renderer._pmremGenerators || new Set();
this._renderer._pmremGenerators.add(this);
};
})(); then in the deepCleanScene helper (renderer._pmremGenerators as Set<THREE.PMREMGenerator>)?.forEach((pmremGenerator) => {
pmremGenerator.dispose();
});
// not clearing the set cos PMREMGenerator is instantiated only once by WebGLCubeUvMaps
// renderer._pmremGenerators.clear(); With this hack, the hanging material and almost all hanging geometries (except one) are disposed. But I'm relying on private method to collect There remain one geometry hanging around related to scene.background usage. But is annoying to see it remaining around. With this one there cannot be a hack from what I've researched. The only place where It would be nice to have an official It would be useful for cases where multiple scene cleanings and repopulating cycles are needed. If not, at least could the background instance be exposed from I can make PR if agreed to expose these. Then when cleaning up:
Most likely exposing cubemaps on Probably it can be suggested to throw away the scene and the renderer and start with new instances. Note: renderer.dispose() does not properly cleanup the hanging texture related to the usage of scene.environment or material.envMap which are related to the internal use of PMREMGenerator. |
I do not vote to expose more components of the renderer. If you call three.js/src/renderers/webgl/WebGLCubeUVMaps.js Lines 97 to 112 in 9c01215
Are you saying this listener does not work correctly? |
If it would be like that: if ( cubemapUV !== undefined ) {
cubeUVmaps.delete( texture );
cubemapUV.dispose();
pmremGenerator.dispose();
} it should clean up properly. Just tested that. Nice idea to focus on that area. |
Description
After deep cleaning the scene, the render info still reports geometries and textures depending on the scenario.
It looks like while traversing the scene we cannot reach certain geometries and textures so that we can dispose them.
Reproduction steps
When no scene.background and no scene.environment, all geometries and textures from scene meshes are disposed properly.
E.g. when using a custom mesh or GLTF without scene.background and scene.environments the scene is cleaned up properly.
When FBX + scene.environment all geometries and textures from scene meshes are disposed properly.
Background issue:
When using only the scene.background (not any meshes in the scene) it is not disposed after scene.background.dispose(); scene.background = null;
Environment issue:
When scene.environment is added in conjunction with custom mesh or GLTF, geometries and textures are still reported after cleaning up the scene.
Strange fact: When scene.environment is added in conjunction with FBX, geometries and textures are zeroed out after cleaning up the scene, which is expected behaviour whatever the scenario would be.
Note:
even if not setting the loaded texture on scene.environment but setting it directly to the mesh.texture.envMap
it triggers the same leaking behaviour after deepClean.
Tested with UltraHDRLoader, RGBELoader, and locally with CubeTexture.
The behaviour is the same, which looks like not being a loader issue.
Code
This is the function used to deep clean the scene.
Live example
https://jsfiddle.net/catalin_enache/Lc319amo/433/
There are some flags in the fiddle to play with in order to trigger some scenario from the described scenarios
Screenshots
No response
Version
0.173.0
Device
Desktop
Browser
Chrome
OS
MacOS
The text was updated successfully, but these errors were encountered: