WebGL 让浏览器可以直接调用 GPU 渲染 3D 图形,而 Three.js 则将底层的复杂性封装成优雅的 JavaScript API。本文将从零开始,带你构建第一个 3D 场景。
一、WebGL 是什么?
WebGL(Web Graphics Library)是一种 JavaScript API,用于在浏览器中渲染高性能的 2D 和 3D 图形。它基于 OpenGL ES 2.0/3.0 标准,不需要任何插件即可运行。过去五年间,WebGPU 作为下一代标准也开始崭露头角,但 WebGL 仍然是最广泛兼容的选择。
用原生 WebGL 绘制一个三角形需要编写顶点着色器、片段着色器、设置缓冲区……几十行代码只为了画一个三角形。这就是 Three.js 存在的意义——它把这些称为"样板代码"的部分彻底封装起来。
二、Three.js 核心概念
Three.js 构建 3D 场景需要四个核心元素:
- Scene(场景):所有物体的容器,相当于 3D 世界的舞台
- Camera(相机):观察视角,常用透视相机(
PerspectiveCamera)模拟人眼 - Renderer(渲染器):将场景通过相机渲染到屏幕,使用
WebGLRenderer - Mesh(网格):几何体(Geometry)加上材质(Material)组成的可见物体
import * as THREE from 'three';
// 1. 创建场景
const scene = new THREE.Scene();
// 2. 创建透视相机 (视角75°, 宽高比, 近裁面0.1, 远裁面1000)
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 3. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 4. 创建一个旋转的立方体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 0x00fff7 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 5. 添加光照
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0, 5, 5);
scene.add(light);
// 6. 动画循环
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
三、进阶:粒子系统和着色器
Three.js 的高级功能可以让效果更加惊艳:
粒子系统(Points)
使用 PointsMaterial 可以创建数千个粒子,常用于星空、烟雾等效果。配合鼠标交互,可以产生本文网站主页那样的动态粒子网络。
自定义着色器(Shader)
通过编写自定义 GLSL 着色器,可以实现超出内置材质的视觉效果——如赛博朋克风格的故障闪烁、流光扫描线等。
// 一个简单的自定义着色器材质
const customMaterial = new THREE.ShaderMaterial({
uniforms: {
uTime: { value: 0 },
uColor: { value: new THREE.Color(0x00fff7) }
},
vertexShader:
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
,
fragmentShader:
uniform vec3 uColor;
uniform float uTime;
varying vec2 vUv;
void main() {
float glow = sin(vUv.x * 20.0 + uTime) * 0.5 + 0.5;
gl_FragColor = vec4(uColor * glow, 1.0);
}
});
四、性能优化建议
- 合并几何体:使用
BufferGeometryUtils.mergeGeometries减少 draw call - 使用 LOD(细节层次):远处物体使用低精度模型
- 纹理压缩:使用 KTX2 或 Basis 压缩格式
- 限制帧率:非交互场景可以锁 30fps 降低功耗
- InstancedMesh:大量相同物体使用实例化渲染
五、推荐学习资源
- Three.js 官方文档
- 官方示例库
- Discover Three.js — 免费电子书
本文是 Xiao Ming 博客系列文章之一。下一篇将探讨零信任架构在企业中的应用。