Hi,
I have a question on memory usage of LoD module in threejs. I have a huge scene where I added several lod instances with just the low details at loading time. When I zoom in, if the camera gets closer to a lod, I asynchronously download the higher detail level and add them to the LoD.
There comes the issue, when I zoom out, I guess the memory is still allocated for the higher level of the LoD. Is there a way to “dispose” the geometry/material associated to the high level of LoD ?
I’m not sure what you mean here. Are you talking about CPU or GPU memory? Do you want to keep the high-resolution levels in the LOD object and only free the underlying data?
In any event, the following guide should explain how to dispose of various three.js entities like materials and geometries. Calling .dispose() on your geometry and material objects will free the GPU geometry buffer data and shader programs. However, as long as you have references to objects of THREE.BufferGeoemtry and THREE.Material, they will stay in memory and not GC collected.
Thanks for your feedback.
I’m talking about CPU memory (altough I’m not sure what happens with GPU memory when the higher level is not displayed).
Correct me If I’m wrong, lod.addLevel(mesh) adds a reference to the mesh, so calling .dispose() on the geometry/material will have no effect, right ?
Would it make sense to have a lod.removeLevel(obj, dist) function ?
I’m not sure I understand the workflow in which this method would be useful. When the user zooms in again, you also need the respective high-resolution LOD levels. It’s definitely no good approach to download, parse and GPU-upload these resources every time when this happens.
I’m not sure I understand the workflow in which this method would be useful. When the user zooms in again, you also need the respective high-resolution LOD levels. It’s definitely no good approach to download, parse and GPU-upload these resources every time when this happens.
I have a scene which is composed of 12 GB high resolutions meshes, where the average size of a mesh is 200mb. I created low/medium resolution meshes with an average size of 1/10 mb. I have one lod instance per mesh. If I keep the high resolution meshes in CPU memory, the memory usage rapidly hits 2 GB. This is why I’m looking for a way to offload CPU memory of these high resolution meshes when the camera is far from the lod.
what you probably want is a loading cache and a custom LOD system. You can write your own loading cache or look for an NPM module, a custom LOD system can probably be built on top of what three.js already offers.
I think I can try to rely on the caching system of the webbrowser to avoid downloading again the most detailed tiles. The LoD mecanism provided by threejs works perfectly for my usecase, but it’s just lacking an API to remove a specific level in a given LoD.
After digging halfway into the source code, I think geometry.dispose() does not remove the data in the geometry object, but removes the GPU-side data. I may be wrong, though. Should be easy to check… Update: Checked with a simple SphereBufferGeometry. The data is not removed when I call dispose().
You can explicitly remove the attributes from the geometry, or simply “lose” all references to it. I guess removing the attributes explicitly is safer, and possibly faster.
highResMesh.geometry.dispose();
lod.remove(highResMesh);
highResMesh = null; //removes another reference
it’s doing some weard stuff. Before lod.remove() call, lod children number is 2 (high and low), and after it’s only one, so from the lod perspective, it seems ok.
But if I print the renderer.info with: console.log(renderer.info);
I see that both geometries/material/texture are still present.
Hm, why do you call lod.remove(highResMesh)? This implies that highResMesh is a child of lod. I thought it was really a level. But there is no method lod.removeLevel yet. Object3D.remove “works” (fails without complaining) when called with an object which is not a child…