阵列模型 · Array Model · ▶ 在线运行案例

阵列模型

你将学到什么

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

效果说明

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

核心概念

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 入门演示、数量少
InstancedMesh 1 大量相同物体(树、草、城市)
合并 Geometry 1 静态场景、不再单独控制

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

实现步骤

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

代码要点


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
            mesh.position.set(i * 20, k * 20, j * 20);
            scene.add(mesh); //网格模型添加到场景中  
        }
    }
}

// AxesHelper
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); //渲染区域
renderer.render(scene, camera); //执行渲染
box.appendChild(renderer.domElement);;


// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景
controls.addEventListener('change', function () {
    renderer.render(scene, camera); //执行渲染操作
    console.log(camera.position)
});//监听鼠标、键盘事件

完整源码:GitHub

小结