Three.js三维可视化

Three.js 入门指南

Three.js 是基于 WebGL 的 JavaScript 3D 库,让你能在浏览器中创建 3D 场景。从数据可视化到游戏开发,从产品展示到虚拟现实,Three.js 降低了 WebGL 的使用门槛。


一、核心三要素

Three.js 的核心由三个要素组成:

要素 作用 类比
Scene(场景) 所有 3D 对象的容器 舞台
Camera(相机) 决定观察场景的视角 摄像机
Renderer(渲染器) 将 3D 场景渲染成 2D 图像 导演
核心理解:Scene 是容器,Camera 是视角,Renderer 负责将 Camera 看到的 Scene 画到 <canvas> 上。

二、快速开始

引入 Three.js

import * as THREE from 'three';

下载地址:https://github.com/mrdoob/three.js

创建场景

const scene = new THREE.Scene();

创建相机

// PerspectiveCamera(视场角, 宽高比, 近裁剪面, 远裁剪面)
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
⚠️ 注意:相机不需要添加到场景中,在 renderer.render(scene, camera) 时直接使用。

创建渲染器

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

renderer.domElement 是一个 <canvas> 元素,Three.js 将 3D 场景渲染到这个画布上。

创建 3D 对象

const geometry = new THREE.BoxGeometry();  // 几何体:定义形状
const material = new THREE.MeshBasicMaterial({ color: 0xB96353 });  // 材质:定义外观
const cube = new THREE.Mesh(geometry, material);  // 网格 = 几何体 + 材质
scene.add(cube);
组件 作用
Geometry 定义形状(顶点和面)
Material 定义外观(颜色、纹理)
Mesh 几何体 + 材质的组合

动画循环

function animate() {
  requestAnimationFrame(animate);

  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;

  renderer.render(scene, camera);
}
animate();
💡 动画原理requestAnimationFrame 在浏览器每次重绘前调用回调函数(通常 60FPS),通过不断修改对象属性并重新渲染,形成动画效果。

三、交互控制:OrbitControls

OrbitControls 让用户通过鼠标与 3D 场景交互:

操作 效果
左键拖动 旋转视角
右键拖动 平移相机
滚轮 缩放
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;  // 启用阻尼(惯性效果)
controls.autoRotate = true;     // 自动旋转

function animate() {
  requestAnimationFrame(animate);
  controls.update();  // 必须在动画循环中更新
  renderer.render(scene, camera);
}
关键点:使用 OrbitControls 时,必须在动画循环中调用 controls.update(),否则阻尼效果不生效。

四、加载 3D 模型

使用 STLLoader 加载 STL 格式模型:

import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js';

const loader = new STLLoader();
loader.load('model.stl', function(geometry) {
  const material = new THREE.MeshLambertMaterial({ color: 0x00ffff });
  const mesh = new THREE.Mesh(geometry, material);

  mesh.rotation.x = -0.5 * Math.PI;  // 摆正模型
  mesh.scale.set(4, 4, 4);           // 缩放
  geometry.center();                 // 居中

  scene.add(mesh);
});

五、添加光照

const light = new THREE.HemisphereLight(0x404040, 0xffffff, 0.8);
light.position.set(0, 1, 0);
scene.add(light);
⚠️ 材质与光照MeshBasicMaterial 不受光照影响,需使用 MeshLambertMaterialMeshPhongMaterial 才能看到光照效果。

六、响应窗口大小

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});

七、完整示例

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

// 场景
const scene = new THREE.Scene();

// 相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
camera.position.z = 5;

// 渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建立方体
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 交互控制
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

// 动画循环
function animate() {
  requestAnimationFrame(animate);

  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;

  controls.update();
  renderer.render(scene, camera);
}
animate();

// 响应窗口大小
window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});
📋 核心流程
  • 创建 Scene、Camera、Renderer 三要素
  • 创建 Geometry + Material → Mesh,添加到场景
  • 在 animate 循环中更新对象状态并渲染
  • 监听窗口变化,更新相机和渲染器尺寸

八、参考资源