Three.js的三大核心组件构成了3D渲染的基本架构,它们之间的关系可以概括为:场景(Scene) 包含所有3D对象和光源,相机(Camera) 决定观察视角,渲染器(Renderer) 负责将场景通过相机视角渲染到HTML元素中。
javascript
// 基本使用流程
const scene = new THREE.Scene(); // 1. 创建场景
const camera = new THREE.PerspectiveCamera(); // 2. 创建相机【此处为最常用的透视相机】
const renderer = new THREE.WebGLRenderer(); // 3. 创建渲染器
// 设置渲染器
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 将场景和相机传递给渲染器
renderer.render(scene, camera);
场景是所有3D对象的容器,它本身是一个树形结构,可以添加各种对象(网格、灯光、摄像机等),并提供统一的坐标空间。
添加和管理对象
javascript
const scene = new THREE.Scene();
// 创建几何体和材质
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
// 添加到场景
scene.add(cube);
// 检查对象
console.log(scene.children); // 查看所有子对象
console.log(scene.getObjectByName('myCube')); // 按名称获取对象
// 移除对象
scene.remove(cube);
// 清空场景
scene.clear();
场景使用场景图管理对象,允许父子关系:
javascript
const group = new THREE.Group();
const cube1 = new THREE.Mesh(geometry, material);
const cube2 = new THREE.Mesh(geometry, material);
cube1.position.x = -2;
cube2.position.x = 2;
group.add(cube1, cube2);
group.position.y = 1;
scene.add(group); // 移动group会影响所有子对象
javascript
// 线性雾
scene.fog = new THREE.Fog(0xcccccc, 10, 50);
// 指数雾
scene.fog = new THREE.FogExp2(0xcccccc, 0.1);
javascript
// 纯色背景
scene.background = new THREE.Color(0x87CEEB);
// 纹理背景
const loader = new THREE.TextureLoader();
loader.load('sky.jpg', function(texture) {
scene.background = texture;
});
// 立方体贴图(天空盒)
const cubeTextureLoader = new THREE.CubeTextureLoader();
scene.background = cubeTextureLoader.load([
'px.png', 'nx.png', // 左右
'py.png', 'ny.png', // 上下
'pz.png', 'nz.png' // 前后
]);

透视相机(PerspectiveCamera) - 最常用
模拟人眼视角,有近大远小的透视效果。
javascript
// 参数:视野角(FOV), 宽高比, 近平面, 远平面
const camera = new THREE.PerspectiveCamera(
75, // 视野角度 (degrees)
window.innerWidth / window.innerHeight, // 宽高比
0.1, // 近平面 (任何比这更近的对象不可见)
1000 // 远平面 (任何比这更远的对象不可见)
);
// 设置相机位置
camera.position.set(0, 0, 5);
camera.lookAt(0, 0, 0); // 看向原点
没有透视效果,所有尺寸保持相同,适合2D游戏或工程图。
javascript
// 参数:左、右、上、下、近、远
const camera = new THREE.OrthographicCamera(
-5, 5, // 左右
5, -5, // 上下 (注意顺序)
0.1, 1000 // 近远平面
);
javascript
// 立方体相机(用于立方体贴图)
const cubeCamera = new THREE.CubeCamera(0.1, 1000, 256);
// 阵列相机(多视角)
const camera = new THREE.ArrayCamera([
new THREE.PerspectiveCamera(),
new THREE.PerspectiveCamera()
]);
javascript
// 位置
camera.position.set(0, 2, 5);
// 旋转
camera.rotation.set(0, Math.PI/4, 0);
// 看向目标
camera.lookAt(new THREE.Vector3(0, 0, 0));
// 使用目标点
const target = new THREE.Vector3(1, 0, 0);
camera.lookAt(target);
javascript
// 1. CameraHelper - 可视化相机范围
const helper = new THREE.CameraHelper(camera);
scene.add(helper);
// 2. 轨道控制器(需要引入OrbitControls)
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 平滑阻尼效果
controls.dampingFactor = 0.05;
// 3. 飞行控制器
import { FlyControls } from 'three/addons/controls/FlyControls.js';
const controls = new FlyControls(camera, renderer.domElement);
controls.movementSpeed = 100;
controls.rollSpeed = Math.PI / 24;
javascript
// 更新投影矩阵(当窗口大小变化时)
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix(); // 必须调用!
renderer.setSize(window.innerWidth, window.innerHeight);
});
WebGLRenderer(最常用)
javascript
const renderer = new THREE.WebGLRenderer({
antialias: true, // 抗锯齿
alpha: true, // 透明背景
precision: 'highp', // 精度
powerPreference: 'high-performance', // 性能偏好
stencil: false, // 禁用模板缓冲区
depth: true, // 启用深度缓冲区
logarithmicDepthBuffer: true // 解决z-fighting
});
// 设置大小和像素比
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); // 防止性能问题
// 添加到DOM
document.body.appendChild(renderer.domElement);
javascript
// WebGL 1.0 渲染器(兼容旧设备)
const renderer = new THREE.WebGL1Renderer();
// CSS3D渲染器(用于HTML元素的3D变换)
const renderer = new THREE.CSS3DRenderer();
// SVG渲染器(矢量图形)
const renderer = new THREE.SVGRenderer();
输出设置
javascript
// 设置背景颜色和透明度
renderer.setClearColor(0x000000, 1); // 颜色, 透明度
// 设置渲染尺寸
renderer.setSize(width, height);
// 设置像素比
renderer.setPixelRatio(window.devicePixelRatio);
// 自动清除颜色、深度、模板缓冲区
renderer.autoClear = true;
// 阴影支持
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 柔和阴影
javascript
// 启用物理正确光照
renderer.physicallyCorrectLights = true;
// 色调映射
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.0;
// 输出编码
renderer.outputEncoding = THREE.sRGBEncoding;
// 开启抗锯齿
renderer.antialias = true;
// 性能监视
const stats = new Stats();
document.body.appendChild(stats.dom);
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
stats.update(); // 更新性能监视器
}
javascript
// 基本渲染循环
function animate() {
requestAnimationFrame(animate);
// 更新场景对象
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
// 渲染场景
renderer.render(scene, camera);
}
animate();
// 带控制的渲染循环
let clock = new THREE.Clock();
let delta = 0;
function animate() {
requestAnimationFrame(animate);
delta = clock.getDelta(); // 获取时间差
// 更新控制器
if (controls) controls.update(delta);
// 更新动画
updateAnimations(delta);
// 渲染
renderer.render(scene, camera);
}
javascript
// 完整示例
function init() {
// 1. 创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x87CEEB);
scene.fog = new THREE.Fog(0x87CEEB, 10, 100);
// 2. 创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.set(0, 5, 10);
camera.lookAt(0, 0, 0);
// 3. 创建渲染器
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;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
// 4. 添加内容
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({
color: 0x00ff00,
roughness: 0.5,
metalness: 0.5
});
const cube = new THREE.Mesh(geometry, material);
cube.castShadow = true;
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, 10, 7.5);
directionalLight.castShadow = true;
scene.add(directionalLight);
// 5. 添加控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
// 6. 处理窗口大小变化
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// 7. 动画循环
function animate() {
requestAnimationFrame(animate);
// 更新对象
cube.rotation.x += 0.01;
cube.rotation.y += 0.005;
// 更新控制器
controls.update();
// 渲染场景
renderer.render(scene, camera);
}
animate();
}
init();
合理设置相机的近远平面,减少渲染范围
使用renderer.setPixelRatio()限制像素比
及时清理不再需要的对象和纹理
使用实例化几何体渲染大量相同对象
javascript
// 清理资源
function disposeObject(object) {
if (object.geometry) object.geometry.dispose();
if (object.material) {
if (Array.isArray(object.material)) {
object.material.forEach(material => material.dispose());
} else {
object.material.dispose();
}
}
}
// 清理场景
function clearScene(scene) {
scene.traverse(disposeObject);
scene.clear();
}
javascript
// 处理响应式
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
window.addEventListener('resize', onWindowResize);
Three.js的三大核心组件构成了3D渲染的基础框架:
场景是容器,管理所有3D对象和它们的层级关系
相机决定观察视角和投影方式,控制哪些内容可见
渲染器负责将场景通过相机视角绘制到屏幕上
理解这三者如何协同工作是掌握Three.js的关键。通过合理的配置和优化,可以创建出高性能、视觉效果出色的3D应用。