最新文章
Three.js 入门与实践:创建惊艳的3D Web体验
发布时间:2025-10-24
热度:
什么是Three.js?
Three.js是一个强大的JavaScript 3D库,它封装了WebGL的复杂API,让开发者能够更轻松地在浏览器中创建和展示3D图形。无论是简单的3D模型展示,还是复杂的交互式3D应用,Three.js都提供了完整的解决方案。
核心概念解析
1. 三大核心组件
// 场景、相机、渲染器 - Three.js的三大核心const scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);const renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);
2. 几何体与材质
// 创建立方体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);camera.position.z = 5;实战项目:创建交互式3D场景
基础场景搭建
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js 3D场景</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { display: block; } </style></head><body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
// 初始化场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x87CEEB);
// 初始化相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 初始化渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
// 添加环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
// 添加定向光
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(10, 20, 5);
scene.add(directionalLight);
</script></body></html>创建复杂3D物体
// 创建地球模型function createEarth() {
const geometry = new THREE.SphereGeometry(2, 32, 32);
const textureLoader = new THREE.TextureLoader();
const material = new THREE.MeshPhongMaterial({
map: textureLoader.load('https://threejs.org/examples/textures/planets/earth_atmos_2048.jpg'),
bumpMap: textureLoader.load('https://threejs.org/examples/textures/planets/earth_normal_2048.jpg'),
bumpScale: 0.05,
specularMap: textureLoader.load('https://threejs.org/examples/textures/planets/earth_specular_2048.jpg'),
specular: new THREE.Color(0x333333)
});
const earth = new THREE.Mesh(geometry, material);
scene.add(earth);
return earth;}// 创建星空背景function createStarfield() {
const starGeometry = new THREE.BufferGeometry();
const starCount = 10000;
const positions = new Float32Array(starCount * 3);
for (let i = 0; i < starCount * 3; i++) {
positions[i] = (Math.random() - 0.5) * 2000;
}
starGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
const starMaterial = new THREE.PointsMaterial({
color: 0xffffff,
size: 1
});
const stars = new THREE.Points(starGeometry, starMaterial);
scene.add(stars);}动画与交互
class InteractiveScene {
constructor() {
this.objects = [];
this.mouse = { x: 0, y: 0 };
this.init();
}
init() {
this.createObjects();
this.setupEventListeners();
this.animate();
}
createObjects() {
// 创建多个旋转立方体
for (let i = 0; i < 10; i++) {
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshPhongMaterial({
color: Math.random() * 0xffffff,
transparent: true,
opacity: 0.8
});
const cube = new THREE.Mesh(geometry, material);
cube.position.set(
(Math.random() - 0.5) * 20,
(Math.random() - 0.5) * 20,
(Math.random() - 0.5) * 20
);
cube.rotationSpeed = {
x: Math.random() * 0.02,
y: Math.random() * 0.02
};
scene.add(cube);
this.objects.push(cube);
}
}
setupEventListeners() {
document.addEventListener('mousemove', (event) => {
this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
});
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
}
animate() {
requestAnimationFrame(() => this.animate());
// 更新物体旋转
this.objects.forEach((obj, index) => {
obj.rotation.x += obj.rotationSpeed.x;
obj.rotation.y += obj.rotationSpeed.y;
// 添加鼠标交互效果
obj.position.y += Math.sin(Date.now() * 0.001 + index) * 0.01;
});
// 相机跟随鼠标
camera.position.x += (this.mouse.x * 5 - camera.position.x) * 0.05;
camera.position.y += (this.mouse.y * 5 - camera.position.y) * 0.05;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}}高级特性探索
1. 加载外部3D模型
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';class ModelLoader {
constructor() {
this.loader = new GLTFLoader();
}
loadModel(url) {
return new Promise((resolve, reject) => {
this.loader.load(url, (gltf) => {
const model = gltf.scene;
scene.add(model);
resolve(model);
}, undefined, reject);
});
}}// 使用示例const modelLoader = new ModelLoader();modelLoader.loadModel('models/robot.glb').then(model => {
model.position.set(0, 0, 0);
model.scale.set(0.5, 0.5, 0.5);});2. 粒子系统
function createParticleSystem() {
const particleCount = 1000;
const positions = new Float32Array(particleCount * 3);
const colors = new Float32Array(particleCount * 3);
for (let i = 0; i < particleCount * 3; i += 3) {
// 位置
positions[i] = (Math.random() - 0.5) * 50;
positions[i + 1] = (Math.random() - 0.5) * 50;
positions[i + 2] = (Math.random() - 0.5) * 50;
// 颜色
colors[i] = Math.random();
colors[i + 1] = Math.random();
colors[i + 2] = Math.random();
}
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
const material = new THREE.PointsMaterial({
size: 0.5,
vertexColors: true,
transparent: true,
opacity: 0.8
});
const particles = new THREE.Points(geometry, material);
scene.add(particles);
return particles;}3. 后期处理效果
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js';function setupPostProcessing() {
const composer = new EffectComposer(renderer);
const renderPass = new RenderPass(scene, camera);
composer.addPass(renderPass);
const bloomPass = new UnrealBloomPass(
new THREE.Vector2(window.innerWidth, window.innerHeight),
1.5, 0.4, 0.85
);
composer.addPass(bloomPass);
return composer;}性能优化技巧
1. 对象池管理
class ObjectPool {
constructor(createObject, maxSize = 100) {
this.createObject = createObject;
this.maxSize = maxSize;
this.pool = [];
}
get() {
if (this.pool.length > 0) {
return this.pool.pop();
}
return this.createObject();
}
release(obj) {
if (this.pool.length < this.maxSize) {
this.pool.push(obj);
}
}}2. 细节层次(LOD)
function setupLOD() {
const lod = new THREE.LOD();
// 高细节模型(近距离)
const highDetailGeometry = new THREE.SphereGeometry(1, 32, 32);
const highDetailMaterial = new THREE.MeshPhongMaterial({ color: 0xff0000 });
const highDetailMesh = new THREE.Mesh(highDetailGeometry, highDetailMaterial);
// 低细节模型(远距离)
const lowDetailGeometry = new THREE.SphereGeometry(1, 8, 8);
const lowDetailMaterial = new THREE.MeshPhongMaterial({ color: 0xff0000 });
const lowDetailMesh = new THREE.Mesh(lowDetailGeometry, lowDetailMaterial);
lod.addLevel(highDetailMesh, 0);
lod.addLevel(lowDetailMesh, 50);
scene.add(lod);}最佳实践
1. 内存管理
class SceneManager {
constructor() {
this.scene = new THREE.Scene();
this.objects = new Set();
}
addObject(object) {
this.scene.add(object);
this.objects.add(object);
}
removeObject(object) {
this.scene.remove(object);
this.objects.delete(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();
}
}
}
clearScene() {
this.objects.forEach(object => this.removeObject(object));
}}2. 响应式设计
class ResponsiveRenderer {
constructor(camera, renderer) {
this.camera = camera;
this.renderer = renderer;
this.setupResizeHandler();
}
setupResizeHandler() {
window.addEventListener('resize', () => {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth, window.innerHeight);
});
}}结语
Three.js为Web开发者打开了3D图形编程的大门。通过掌握核心概念、实践项目和优化技巧,你可以创建出令人惊叹的3D Web体验。记住,优秀的3D应用不仅需要技术实力,更需要对用户体验和性能优化的深入理解。
随着WebGL技术的不断发展,Three.js将继续在游戏开发、数据可视化、产品展示、教育应用等领域发挥重要作用。开始你的Three.js之旅,探索3D Web开发的无限可能!












冀公网安备