经纬志
首页 / three.js / API 文档

Scene

先看结论

场景图的根节点,持有物体、灯光与背景设置,本身没有几何与材质。

最后验证 2026-11-03 · three.js 0.160.0 · 更新 2026-10-27 · 引用本文
new THREE.Scene() → Scene

属性

属性类型说明
backgroundColor / Texture / CubeTexture / null纯色或贴图背景,设为 null 时透明(渲染器需 alpha: true)
environmentTexture / nullPBR 材质的环境反射来源,通常是 PMREM 处理过的贴图
fogFog / FogExp2 / null线性或指数雾,用来压暗远处、表达距离
overrideMaterialMaterial / null强制所有物体使用同一材质,常用于调试与深度预渲染
childrenObject3D[]直接子节点,只读引用,增删用方法
autoUpdateboolean为 false 时渲染器不自动更新世界矩阵
matrixWorldAutoUpdateboolean是否每帧自动更新自身世界矩阵

常用方法

方法说明
add(object, ...)添加子节点。添加即从原父节点移除,一个对象只能有一个父节点
remove(object, ...)移除子节点,但不释放几何、材质与贴图
clear()移除全部直接子节点,同样不释放资源
getObjectByName(name)按 name 深度查找,返回第一个匹配项
getObjectByProperty(name, value)按任意属性查找
traverse(fn)深度优先遍历自身与所有后代
traverseVisible(fn)只遍历可见分支,隐藏的子树直接跳过
updateMatrixWorld(force)手动更新世界矩阵,静态场景可调用一次后停止自动更新
toJSON()序列化为 three 的 JSON 结构,贴图与模型需自行处理

背景、雾与环境

const scene = new THREE.Scene();

// 纯色背景
scene.background = new THREE.Color(0x0d1117);

// 线性雾:near 之内不受影响,far 之外完全被雾色覆盖
scene.fog = new THREE.Fog(0x0d1117, 400, 1800);

// 需要全局反射时,用 PMREM 生成环境贴图
// import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
const pmrem = new THREE.PMREMGenerator(renderer);
const envTarget = pmrem.fromScene(new RoomEnvironment(), 0.04);
scene.environment = envTarget.texture;
pmrem.dispose();

环境贴图换掉后,旧的渲染目标要调用 envTarget.dispose() 释放, 否则每换一次环境就多占一份显存。

雾色通常与背景色一致,两者不一致时远处会出现一条明显的分界。 大面积地形场景加雾能显著降低远处的视觉噪声,也能掩盖瓦片边界。

遍历与批量操作

// 给所有网格统一开启投影与阴影接收
scene.traverse(function (obj) {
  if (obj.isMesh) {
    obj.castShadow = true;
    obj.receiveShadow = true;
  }
});

// 按名称取回建模软件里命名的节点
const roof = scene.getObjectByName('roof_level_3');

traverse 每帧调用会带来不必要的开销,适合在加载完成或配置变更时执行一次。 需要在动画里频繁查找的对象,应当提前保存引用,而不是反复遍历。

资源释放

从场景移除对象不会释放显存。几何体、材质、贴图各自持有 GPU 资源,必须显式销毁:

function disposeObject(root) {
  root.traverse(function (obj) {
    if (obj.geometry) obj.geometry.dispose();

    const material = obj.material;
    if (!material) return;

    (Array.isArray(material) ? material : [material]).forEach(function (m) {
      Object.keys(m).forEach(function (key) {
        const value = m[key];
        if (value && value.isTexture) value.dispose();
      });
      m.dispose();
    });
  });
}

scene.remove(layer);
disposeObject(layer);

单页应用里反复加载与卸载图层时,漏掉这一步的典型表现是显存持续上涨, 最后 WebGL 上下文丢失,页面变成空白。

场景不是容器。Scene 继承自 Object3D, 同样有 position、rotation、scale。 整体平移场景会连背景与雾的参考一起改变,通常应通过相机或一个专用组来做整体位移。

引用本文

经纬志(2026)。《Scene》。https://www.jingweizhi.com/three/api/scene.html(访问日期 2026-11-03)。