无法处理 three.js 应用程序中不需要的几何体
Cannot dispose of unwanted geometry in three.js application
在这个最小的示例中,我将 THREE.SphereGeometry 添加到 THREE.Group,然后将组添加到场景中。
渲染场景后,我想从场景中移除组并处理几何体。
<html>
<head>
<title>memory-leak-demo-01</title>
<script type='module'>
import * as THREE from '../lib/three-js-129/build/three.module.js';
let canvas = document.createElement('canvas');
let renderer = new THREE.WebGLRenderer({ canvas:canvas, antialias: true });
let camera = new THREE.PerspectiveCamera();
let scene = new THREE.Scene();
scene.add(camera);
function getGroup(){
let group = new THREE.Group();
const geometry = new THREE.SphereGeometry( 5, 8, 8 );
const material = new THREE.MeshBasicMaterial( {color: 0xffff00, wireframe: true} );
group.add(new THREE.Mesh( geometry, material ));
return group;
}
for(let i=0; i<1000; i++){
let myGroup = getGroup();
scene.add(myGroup);
renderer.render(scene, camera);
scene.remove(myGroup);
console.log(`${i} renderer.info.memory: ${JSON.stringify(renderer.info.memory)}`);
}
</script>
</head>
</html>
问题是即使 myGroup 已从场景中删除,控制台日志记录显示几何图形并未从内存中删除。
992 renderer.info.memory: {"geometries":993,"textures":0}
993 renderer.info.memory: {"geometries":994,"textures":0}
994 renderer.info.memory: {"geometries":995,"textures":0}
995 renderer.info.memory: {"geometries":996,"textures":0}
996 renderer.info.memory: {"geometries":997,"textures":0}
997 renderer.info.memory: {"geometries":998,"textures":0}
998 renderer.info.memory: {"geometries":999,"textures":0}
999 renderer.info.memory: {"geometries":1000,"textures":0}
如何对它们执行 .dispose()?我只想处理组中的几何图形。场景包含我想保留的其他对象。
在我正在处理的实际应用程序中,组中有许多几何图形,并且在每个 requestAnimationFrame 上都会从场景中添加和删除组。内存被消耗,直到我的系统死机。
我在这里放了一个包含以上代码的页面:
https://mytestpages.com/three/memory-leak-demo-01.html
此页面说明了相同的问题,但明显绘制了球体:
https://mytestpages.com/three/memory-leak-demo-02.html
理想情况下,您的清理应该如下所示:
for(let i=0; i<1000; i++){
let myGroup = getGroup();
scene.add(myGroup);
renderer.render(scene, camera);
scene.remove(myGroup);
const mesh = myGroup.children[ 0 ];
mesh.geometry.dispose(); // FIX
mesh.material.dispose(); // FIX
console.log(`${i} renderer.info.memory: ${JSON.stringify(renderer.info.memory)}`);
}
在这个最小的示例中,我将 THREE.SphereGeometry 添加到 THREE.Group,然后将组添加到场景中。 渲染场景后,我想从场景中移除组并处理几何体。
<html>
<head>
<title>memory-leak-demo-01</title>
<script type='module'>
import * as THREE from '../lib/three-js-129/build/three.module.js';
let canvas = document.createElement('canvas');
let renderer = new THREE.WebGLRenderer({ canvas:canvas, antialias: true });
let camera = new THREE.PerspectiveCamera();
let scene = new THREE.Scene();
scene.add(camera);
function getGroup(){
let group = new THREE.Group();
const geometry = new THREE.SphereGeometry( 5, 8, 8 );
const material = new THREE.MeshBasicMaterial( {color: 0xffff00, wireframe: true} );
group.add(new THREE.Mesh( geometry, material ));
return group;
}
for(let i=0; i<1000; i++){
let myGroup = getGroup();
scene.add(myGroup);
renderer.render(scene, camera);
scene.remove(myGroup);
console.log(`${i} renderer.info.memory: ${JSON.stringify(renderer.info.memory)}`);
}
</script>
</head>
</html>
问题是即使 myGroup 已从场景中删除,控制台日志记录显示几何图形并未从内存中删除。
992 renderer.info.memory: {"geometries":993,"textures":0}
993 renderer.info.memory: {"geometries":994,"textures":0}
994 renderer.info.memory: {"geometries":995,"textures":0}
995 renderer.info.memory: {"geometries":996,"textures":0}
996 renderer.info.memory: {"geometries":997,"textures":0}
997 renderer.info.memory: {"geometries":998,"textures":0}
998 renderer.info.memory: {"geometries":999,"textures":0}
999 renderer.info.memory: {"geometries":1000,"textures":0}
如何对它们执行 .dispose()?我只想处理组中的几何图形。场景包含我想保留的其他对象。
在我正在处理的实际应用程序中,组中有许多几何图形,并且在每个 requestAnimationFrame 上都会从场景中添加和删除组。内存被消耗,直到我的系统死机。
我在这里放了一个包含以上代码的页面: https://mytestpages.com/three/memory-leak-demo-01.html
此页面说明了相同的问题,但明显绘制了球体: https://mytestpages.com/three/memory-leak-demo-02.html
理想情况下,您的清理应该如下所示:
for(let i=0; i<1000; i++){
let myGroup = getGroup();
scene.add(myGroup);
renderer.render(scene, camera);
scene.remove(myGroup);
const mesh = myGroup.children[ 0 ];
mesh.geometry.dispose(); // FIX
mesh.material.dispose(); // FIX
console.log(`${i} renderer.info.memory: ${JSON.stringify(renderer.info.memory)}`);
}