Three.js清空场景后无法渲染新内容,部分删除方式存在元素残留的问题
Three.js清空场景后无法渲染新内容,部分删除方式存在元素残留的问题
嗨,我看了你遇到的Three.js场景清空问题,刚好之前也踩过类似的坑,给你分析下原因和解决方案:
第一个问题:清空所有元素后无法渲染新内容
你用this.scene.remove.apply(this.scene, this.scene.children)或者scene.clear()把场景里所有子元素都删掉了,但你的场景里还包含**环境光(AmbientLight)和方向光(DirectionalLight)**啊!这些灯光是渲染物体必不可少的,删掉之后新添加的Mesh没有光照,自然看起来像“没渲染”——其实物体已经在场景里了,只是因为没光看不到而已。
而且scene.clear()会彻底清空场景里的所有对象,包括你之前添加的地面Plane,后续也没重新创建,这也会影响显示。
第二个问题:forEach删除元素存在残留
你用this.scene.children.forEach(...)遍历删除的时候,会因为遍历过程中修改了原数组(删除元素导致数组长度变化),导致部分元素被跳过。举个例子:如果数组是[A,B,C],删除A后数组变成[B,C],下一次循环索引跳到1,会直接取到C,B就被漏掉了,所以需要多次调用才能删干净。
正确的解决方案
我们只需要删除自己生成的房屋Mesh,保留灯光、地面这些基础元素,同时避免遍历原数组时修改它,具体代码如下:
build(layers) { let height = 0; // 用扩展运算符创建children的副本,避免遍历原数组时因删除元素导致漏删 [...this.scene.children].forEach((child) => { // 只删除我们自己生成的Mesh,保留地面Plane和灯光 if (child.isMesh && child !== this.plane) { this.scene.remove(child); // 记得释放几何体和材质的内存,避免内存泄漏 child.geometry.dispose(); child.material.dispose(); } }); layers.forEach(layer => { for (let y = 0; y < GRID_SIZE; y++) { for (let x = 0; x < GRID_SIZE; x++) { if (layer.grid[y][x] != null) { this.scene.add(layer.grid[y][x].get3DVersion(x, y, height)); } } } height += layer.getTotalHeight(); }); }
另外补充两个小Tips:
- 永远不要随便用
scene.clear(),除非你确定要彻底清空所有元素,之后还会重新添加灯光、地面等基础组件。 - 删除Mesh时一定要调用
geometry.dispose()和material.dispose(),不然会造成内存泄漏,尤其是频繁更新场景的情况下。
备注:内容来源于stack exchange,提问作者Carmen Sirgo López
相关产品推荐
相关产品推荐

