Skip to content

阵列模型

Array Model

▶ 在线运行案例

阵列模型

你将学到什么

  • 用循环批量创建 Mesh 的基本方法
  • 共享 Geometry/Material 的内存优化
  • 1000 个独立 Mesh 的性能隐患与 InstancedMesh 方向

效果说明

10×10×10 = 1000 个红色小立方体 排列成三维矩阵。OrbitControls 旋转时可感受规模。

核心概念

js
for (let i = 0; i < 10; i++)
  for (let j = 0; j < 10; j++)
    for (let k = 0; k < 10; k++) {
      const mesh = new THREE.Mesh(geometry, material);
      mesh.position.set(i * 20, k * 20, j * 20);
      scene.add(mesh);
    }
做法draw call适用
1000 个 Mesh~1000入门演示、数量少
InstancedMesh1大量相同物体(树、草、城市)
合并 Geometry1静态场景、不再单独控制

本案例 共享 同一个 geometrymaterial 实例,节省 GPU 内存,但 draw call 仍是 1000 次——这是性能瓶颈所在。

实现步骤

  1. 创建一个 BoxGeometry(5,5,5)MeshBasicMaterial
  2. 三重循环创建 Mesh,间距 20
  3. OrbitControls + change 事件渲染

代码要点

js
const geometry = new THREE.BoxGeometry(5, 5, 5);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });

for (let i = 0; i < 10; i++)
  for (let j = 0; j < 10; j++)
    for (let k = 0; k < 10; k++) {
      const mesh = new THREE.Mesh(geometry, material);
      mesh.position.set(i * 20, k * 20, j * 20);
      scene.add(mesh);
    }

优化方向

万级相同物体 → InstancedMesh;静态合并 → BufferGeometryUtils.mergeGeometries()

源码

js
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(5, 5, 5);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });

for (let i = 0; i < 10; i++) {
    for (let j = 0; j < 10; j++) {
        for (let k = 0; k < 10; k++) {
            const mesh = new THREE.Mesh(geometry, material);
            mesh.position.set(i * 20, k * 20, j * 20);
            scene.add(mesh);
        }
    }
}

const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);

const camera = new THREE.PerspectiveCamera();
camera.position.set(500, 500, 500);
camera.lookAt(0, 50, 0);

const renderer = new THREE.WebGLRenderer();
const box = document.getElementById('box');
renderer.setSize(box.clientWidth, box.clientHeight);
box.appendChild(renderer.domElement);

const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', () => renderer.render(scene, camera));
renderer.render(scene, camera);

小结

入门案例 · Three.js · 11/15