跳到主要内容

环境搭建

在开始 Three.js 开发之前,我们需要搭建一个合适的开发环境。本章将介绍几种常见的环境配置方式,从最简单的 CDN 引入到现代化的构建工具配置。

浏览器要求

Three.js 依赖 WebGL 进行 3D 渲染,因此需要支持 WebGL 的现代浏览器。主流浏览器的最新版本都支持 WebGL:

  • Chrome 9+
  • Firefox 4+
  • Safari 5.1+
  • Edge 12+
  • Opera 12+

你可以在浏览器中访问 get.webgl.org 来检测当前浏览器是否支持 WebGL。

方式一:使用 CDN

最简单的方式是通过 CDN 直接引入 Three.js。这种方式适合快速原型开发和学习的初期阶段。

创建一个 HTML 文件,内容如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js 示例</title>
<style>
body {
margin: 0;
overflow: hidden;
}
canvas {
display: block;
}
</style>
</head>
<body>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@latest/build/three.module.js",
"three/addons/": "https://unpkg.com/three@latest/examples/jsm/"
}
}
</script>

<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

// 创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x1a1a2e);

// 创建相机
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);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);

// 添加轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

// 创建一个立方体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 0x00ff88 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 添加光源
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 5, 5);
scene.add(directionalLight);

// 动画循环
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);
});
</script>
</body>
</html>

这个例子使用了 ES Modules 和 importmap。importmap 告诉浏览器如何解析模块导入路径,让我们可以使用简洁的模块名称而不是完整的 URL。

关键点说明:

antialias: true 开启抗锯齿,让边缘更平滑。

setPixelRatio 设置设备像素比,在高分辨率屏幕上显示更清晰。

OrbitControls 是一个扩展控件,让用户可以用鼠标旋转、缩放、平移视角。

方式二:使用 npm 和构建工具

对于正式项目,推荐使用 npm 管理依赖,配合 Vite 或 Webpack 等构建工具。

使用 Vite(推荐)

Vite 是一个现代化的前端构建工具,启动速度快,配置简单。

首先确保已安装 Node.js(建议 18+ 版本),然后执行:

# 创建项目
npm create vite@latest threejs-demo -- --template vanilla

# 进入项目目录
cd threejs-demo

# 安装 Three.js
npm install three

# 启动开发服务器
npm run dev

项目创建后,修改 main.js 文件:

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

// 初始化场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x1a1a2e);

// 初始化相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.set(0, 0, 5);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);

// 轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;

// 创建物体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({
color: 0x00ff88,
metalness: 0.3,
roughness: 0.4
});
const cube = new THREE.Mesh(geometry, material);
cube.castShadow = true;
scene.add(cube);

// 地面
const groundGeometry = new THREE.PlaneGeometry(10, 10);
const groundMaterial = new THREE.MeshStandardMaterial({ color: 0x333344 });
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2;
ground.position.y = -1;
ground.receiveShadow = true;
scene.add(ground);

// 光源
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 10, 5);
directionalLight.castShadow = true;
directionalLight.shadow.mapSize.width = 2048;
directionalLight.shadow.mapSize.height = 2048;
scene.add(directionalLight);

// 动画循环
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);
});

使用 Webpack

如果你需要在现有的 Webpack 项目中集成 Three.js:

npm install three

webpack 配置通常不需要特殊处理,Three.js 会自动处理模块导入。

方式三:使用 TypeScript

Three.js 提供了完整的 TypeScript 类型定义,在 TypeScript 项目中使用可以获得更好的类型提示和代码补全。

# 创建 Vite + TypeScript 项目
npm create vite@latest threejs-ts-demo -- --template vanilla-ts

cd threejs-ts-demo
npm install three

TypeScript 中的使用方式与 JavaScript 基本相同:

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

class ThreeScene {
private scene: THREE.Scene;
private camera: THREE.PerspectiveCamera;
private renderer: THREE.WebGLRenderer;
private controls: OrbitControls;
private cube: THREE.Mesh;

constructor() {
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(0x1a1a2e);

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

this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(this.renderer.domElement);

this.controls = new OrbitControls(this.camera, this.renderer.domElement);

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 0x00ff88 });
this.cube = new THREE.Mesh(geometry, material);
this.scene.add(this.cube);

const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 5, 5);
this.scene.add(light);

this.scene.add(new THREE.AmbientLight(0xffffff, 0.5));

this.setupEventListeners();
this.animate();
}

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

private animate(): void {
requestAnimationFrame(() => this.animate());

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

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

new ThreeScene();

开发工具推荐

VS Code 扩展

Three.js Snippets:提供 Three.js 代码片段,加快编码速度。

GLSL Lint:如果你编写自定义着色器,这个扩展可以检查 GLSL 语法。

Live Server:在开发时自动刷新页面。

调试工具

Chrome DevTools:浏览器自带的开发者工具,可以检查 WebGL 上下文、性能等。

Three.js Inspector:Chrome 扩展,可以检查场景中的对象层级、属性等。

Spector.js:WebGL 调试工具,可以捕获每一帧的 WebGL 调用。

常见问题

黑屏问题

如果页面显示黑屏,检查以下几点:

  1. 确认 WebGL 可用
  2. 检查相机位置是否在物体内部或太远
  3. 确认场景中有光源(如果使用需要光照的材质)
  4. 检查控制台是否有错误信息

性能问题

如果渲染卡顿,可以尝试:

  1. 减少几何体的顶点数量
  2. 降低渲染器的像素比
  3. 关闭不必要的阴影
  4. 使用 requestAnimationFrame 而不是 setInterval

模块导入问题

如果遇到模块导入错误:

  1. 确保使用 type="module" 或构建工具
  2. 检查 importmap 配置是否正确
  3. 确认 Three.js 版本兼容性

下一步

环境搭建完成后,我们就可以开始学习 Three.js 的核心概念了。下一章将详细介绍场景、相机和渲染器这三个最基础也是最重要的组件。