Group
不带几何与材质的容器节点,用来把多个对象组织成一个整体,共享同一套变换。
属性与方法
Group 继承自 Object3D,具备完整的位置、旋转、缩放与可见性,
方法上就是场景图的标准操作:
| 成员 | 说明 |
|---|---|
position / rotation / scale | 组内所有子节点共享这层变换 |
visible | 为 false 时整组跳过渲染,是最轻量的图层开关 |
renderOrder | 排序优先级,影响透明物体的绘制顺序 |
add(object) | 添加子节点,会从原父节点移除 |
remove(object) | 移除子节点,不释放资源 |
clear() | 移除全部直接子节点 |
attach(object) | 添加子节点但保持其世界变换不变 |
traverse(fn) | 遍历组内所有后代 |
matrixAutoUpdate | 静态组可设为 false,手动更新矩阵以省开销 |
按图层分组
const buildings = new THREE.Group();
buildings.name = 'layer-buildings';
const roads = new THREE.Group();
roads.name = 'layer-roads';
scene.add(buildings, roads);
// 各图层独立开关,不影响其他内容
roads.visible = false;
// 整体平移一个图层
buildings.position.set(0, 0.2, 0);
用组管理图层,比逐个设置 visible 更清晰,也便于整体做淡入淡出、
整体旋转或整体挂到另一个坐标系下。
用组承载局部坐标系
三维场景里经常需要「以某个点为原点」搭建局部内容,例如把一栋建筑放在它的场地中心。
把建筑放进组,组的 position 就是场地中心,建筑内部坐标可以保持小数值,
既方便建模,也避免大坐标带来的浮点精度问题。
// 场地中心在大地坐标中的局部位置
const site = new THREE.Group();
site.position.set(1240, 0, -860);
// 建筑内部坐标围绕 (0,0,0) 建模
const building = new THREE.Mesh(buildingGeometry, buildingMaterial);
building.position.set(0, 12, 0);
site.add(building);
scene.add(site);
// 取世界坐标
const world = new THREE.Vector3();
building.getWorldPosition(world);
调整轴心
旋转默认绕对象的局部原点。若模型原点在角上,旋转会像绕墙角转门一样甩出去。 把模型放进一个组,让组的原点位于期望的旋转中心,再旋转组,就能得到绕中心的旋转。
const pivot = new THREE.Group();
pivot.position.set(0, 1.5, 0); // 期望的旋转中心
model.position.sub(pivot.position); // 把模型相对中心偏移
pivot.add(model);
scene.add(pivot);
pivot.rotation.y += 0.01; // 绕中心自转
组与实例化
Group 只是组织手段,不会减少绘制调用:组里有一百个网格,仍然是一百次绘制。
需要降低调用数时,用 InstancedMesh 或合并几何体。
组适合表达「逻辑上是一层」的内容,性能优化要另做。
常见问题
组不可见,但子对象单独添加时可见
检查组的 visible,以及父级的 visible。
可见性是逐级传递的,任何一层为 false,整棵子树都会被跳过。
加入组之后位置突然变了
子对象的 position 是相对父节点的局部坐标。加入带位移的组后,
原来的世界位置会被叠加组的变换。要保留世界位置,应使用 group.attach(obj),
它会自动换算局部坐标。
给组命名。加载模型、拆分图层后,用 name 标记每个组的用途,
调试时可以直接 getObjectByName 找到它,也方便在导出结构里核对层级。
经纬志(2026)。《Group》。https://www.jingweizhi.com/three/api/group.html(访问日期 2026-11-03)。