本文档涵盖了Three.js中粒子特效的关键概念和实现方法,基于实际代码示例进行讲解。
1. 粒子系统基础
1.1 点材质 (PointsMaterial) 设置
点材质是创建粒子特效的基础,可以通过多种参数配置粒子外观:
// 设置点材质
const pointsMaterial = new THREE.PointsMaterial();
pointsMaterial.size = 0.1; // 粒子大小
pointsMaterial.color.set(0xfff000); // 粒子颜色
pointsMaterial.sizeAttenuation = true; // 是否根据相机深度衰减粒子大小
pointsMaterial.sizeAttenuation = true; // 相机深度衰减
1.2 粒子纹理配置
为了增强粒子的视觉效果,通常会使用纹理:
// 载入纹理
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load("./textures/particles/2.png");
// 设置点材质纹理
pointsMaterial.map = texture; // 纹理贴图
pointsMaterial.alphaMap = texture; // 透明度贴图
pointsMaterial.transparent = true; // 启用透明度
pointsMaterial.depthWrite = false; // 禁用深度写入
pointsMaterial.blending = THREE.AdditiveBlending; // 混合模式
2. 粒子几何体创建
2.1 使用缓冲几何体 (BufferGeometry)
高效的粒子系统通常使用缓冲几何体来存储大量顶点数据:
// 创建粒子几何体
const particlesGeometry = new THREE.BufferGeometry();
const count = 5000; // 粒子数量
// 设置缓冲区数组
const positions = new Float32Array(count * 3); // 位置数组
const colors = new Float32Array(count * 3); // 颜色数组
// 设置顶点位置
for (let i = 0; i < count * 3; i++) {
positions[i] = (Math.random() - 0.5) * 100; // 随机位置
colors[i] = Math.random(); // 随机颜色
}
// 将属性添加到几何体
particlesGeometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
particlesGeometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));
2.2 从现有几何体创建粒子
可以从现有的几何体(如球体)转换为粒子:
// 创建球几何体
const sphereGeometry = new THREE.SphereBufferGeometry(3, 30, 30);
// 删除UV属性(如果不需要纹理映射)
delete sphereGeometry.attributes.uv;
// 创建粒子系统
const points = new THREE.Points(sphereGeometry, pointsMaterial);
scene.add(points);
3. 星河粒子系统
3.1 基础星河效果
创建具有随机分布的星河效果:
// 生成星河粒子
const generateGalaxy = () => {
geometry = new THREE.BufferGeometry();
const positions = new Float32Array(params.count * 3);
const colors = new Float32Array(params.count * 3);
// 循环生成点
for (let i = 0; i < params.count; i++) {
// 当前的点应该在哪一条分支的角度上
const branchAngel = (i % params.branch) * ((2 * Math.PI) / params.branch);
// 当前点距离圆心的距离
const distance = Math.random() * params.radius * Math.pow(Math.random(), 3);
const current = i * 3;
// 随机偏移
const randomX = (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 5;
const randomY = (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 5;
const randomZ = (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 5;
// 计算最终位置
positions[current] = Math.cos(branchAngel + distance * params.rotateScale) * distance + randomX;
positions[current + 1] = 0 + randomY;
positions[current + 2] = Math.sin(branchAngel + distance * params.rotateScale) * distance + randomZ;
// 混合颜色,形成渐变色
const mixColor = centerColor.clone();
mixColor.lerp(endColor, distance / params.radius);
colors[current] = mixColor.r;
colors[current + 1] = mixColor.g;
colors[current + 2] = mixColor.b;
}
geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
geometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));
// 设置点材质
material = new THREE.PointsMaterial({
size: params.size,
sizeAttenuation: true,
depthWrite: false,
blending: THREE.AdditiveBlending,
map: particlesTexture,
alphaMap: particlesTexture,
transparent: true,
vertexColors: true, // 使用顶点颜色
});
points = new THREE.Points(geometry, material);
scene.add(points);
};
4. 雪花粒子系统
4.1 多层雪花效果
创建多个层次的雪花粒子系统:
function createPoints(url, size = 0.5) {
const particlesGeometry = new THREE.BufferGeometry();
const count = 10000;
// 设置缓冲区数组
const positions = new Float32Array(count * 3);
const colors = new Float32Array(count * 3);
// 设置顶点
for (let i = 0; i < count * 3; i++) {
positions[i] = (Math.random() - 0.5) * 100; // 在空间内随机分布
colors[i] = Math.random(); // 随机颜色
}
particlesGeometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
particlesGeometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));
// 设置点材质
const pointsMaterial = new THREE.PointsMaterial();
pointsMaterial.size = size; // 不同大小的粒子
pointsMaterial.color.set(0xfff000);
pointsMaterial.sizeAttenuation = true;
// 载入纹理
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load(`./textures/particles/${url}.png`);
pointsMaterial.map = texture;
pointsMaterial.alphaMap = texture;
pointsMaterial.transparent = true;
pointsMaterial.depthWrite = false;
pointsMaterial.blending = THREE.AdditiveBlending;
pointsMaterial.vertexColors = true; // 启用顶点颜色
const points = new THREE.Points(particlesGeometry, pointsMaterial);
scene.add(points);
return points;
}
// 创建多层雪花效果
const points = createPoints("1", 1.5);
const points2 = createPoints("xh", 1);
const points3 = createPoints("xh", 2);
4.2 粒子动画
为粒子系统添加动画效果:
function render() {
let time = clock.getElapsedTime();
// 旋转动画
points.rotation.x = time * 0.3;
points2.rotation.x = time * 0.5;
points2.rotation.y = time * 0.4;
points3.rotation.x = time * 0.2;
points3.rotation.y = time * 0.2;
controls.update();
renderer.render(scene, camera);
requestAnimationFrame(render);
}
5. 渲染器配置
5.1 基础渲染器设置
针对粒子系统优化渲染器:
// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
// 开启场景中的阴影贴图
renderer.shadowMap.enabled = true;
renderer.physicallyCorrectLights = true;
// 将渲染器添加到DOM
document.body.appendChild(renderer.domElement);
6. 粒子系统优化技巧
6.1 混合模式
使用适当的混合模式提升视觉效果:
// 加法混合,常用于发光效果
pointsMaterial.blending = THREE.AdditiveBlending;
6.2 深度写入控制
控制粒子的深度写入行为:
// 禁用深度写入,避免粒子间的遮挡问题
pointsMaterial.depthWrite = false;
6.3 粒子大小衰减
根据距离调整粒子大小:
// 启用大小衰减,远处的粒子看起来更小
pointsMaterial.sizeAttenuation = true;
7. 控制器和辅助工具
7.1 轨道控制器
添加交互式视角控制:
// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真实效果
controls.enableDamping = true;
// 添加坐标轴辅助器
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
8. 响应式设计
处理窗口大小变化:
// 监听画面变化,更新渲染画面
window.addEventListener("resize", () => {
// 更新摄像头
camera.aspect = window.innerWidth / window.innerHeight;
// 更新摄像机的投影矩阵
camera.updateProjectionMatrix();
// 更新渲染器
renderer.setSize(window.innerWidth, window.innerHeight);
// 设置渲染器的像素比
renderer.setPixelRatio(window.devicePixelRatio);
});
总结
本章详细介绍了Three.js中粒子特效的各个方面,包括:
- 粒子系统基础概念
- 点材质的配置和优化
- 缓冲几何体的使用
- 星河和雪花粒子系统的创建
- 粒子动画和交互
- 渲染优化技巧
通过合理运用这些技术,可以创建出丰富多彩的粒子特效,如星系、雪花、烟雾、火焰等视觉效果。关键在于理解粒子的几何体构建、材质配置以及性能优化方法,从而在保证视觉效果的同时维持良好的运行性能。