Three.js三维可视化
- 前端开发
- 2024-05-11
- 1034热度
- 0评论
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 不受光照影响,需使用 MeshLambertMaterial 或 MeshPhongMaterial 才能看到光照效果。
六、响应窗口大小
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 循环中更新对象状态并渲染
- 监听窗口变化,更新相机和渲染器尺寸