You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 19:55:30