1、粒子系统基础:什么是粒子系统、粒子系统的应用场景、Three.js粒子系统概述
什么是粒子系统?
粒子系统,说白了就是「用大量小点来模拟复杂效果」的技术。
我刚开始接触图形学的时候,觉得这玩意儿挺玄乎的。后来自己动手做了一遍,才发现原理其实很简单——你有一堆小点,每个点都有自己的位置、颜色、大小、速度。然后你让它们动起来,就形成了各种炫酷的效果。
每个粒子通常包含这些属性:
- 位置:粒子在三维空间中的坐标
- 颜色:可以是固定颜色,也可以随时间变化
- 大小:粒子的视觉尺寸
- 速度:运动方向和速率
- 生命周期:粒子从出生到消亡的时间
- 透明度:控制粒子的可见程度
你想想看,一个粒子确实没什么好看的。但几千个、几万个粒子同时运动,就能模拟出火焰、烟雾、星空、雨雪……这就是粒子系统的魅力。
核心思想:用大量简单元素的集体行为,模拟复杂自然现象。
粒子系统的应用场景
我在项目中用过不少粒子效果,这里列几个最常见的场景:
| 场景 | 描述 | 粒子数量参考 |
|---|---|---|
| 星空背景 | 静态或缓慢旋转的星空,常用于太空主题 | 1000-5000 |
| 火焰效果 | 粒子从底部升起,颜色从黄变红再变透明 | 500-2000 |
| 雨雪天气 | 大量粒子从天空下落,模拟降雨或飘雪 | 5000-20000 |
| 烟雾/雾气 | 粒子缓慢扩散,透明度逐渐降低 | 1000-5000 |
| 魔法/技能特效 | 粒子沿特定轨迹运动,常用于游戏 | 500-3000 |
| 数据可视化 | 用粒子展示数据分布或流动 | 10000-100000 |
嗯,这里要注意——不是粒子越多越好。我见过有人一上来就搞十万个粒子,结果手机端直接卡成PPT。要根据目标平台和效果需求来定。
Three.js粒子系统概述
Three.js 里做粒子系统,主要有两种方式:
1. Points(点云)
这是最常用的方式。Three.js 提供了 THREE.Points 和 THREE.PointsMaterial,用起来非常方便。
// 创建一个最简单的粒子系统
const geometry = new THREE.BufferGeometry();
const positions = new Float32Array(1000 * 3);
for (let i = 0; i < 1000; i++) {
positions[i * 3] = (Math.random() - 0.5) * 100;
positions[i * 3 + 1] = (Math.random() - 0.5) * 100;
positions[i * 3 + 2] = (Math.random() - 0.5) * 100;
}
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
const material = new THREE.PointsMaterial({
color: 0xffffff,
size: 0.5,
transparent: true
});
const particles = new THREE.Points(geometry, material);
scene.add(particles);
这段代码干了什么?说白了就是:
- 生成了1000个随机位置
- 塞进 BufferGeometry 里
- 用 PointsMaterial 控制外观
- 最后加到场景中
个人经验:我习惯把粒子位置单独存一份副本,方便做动画更新。直接操作 geometry 的属性虽然也行,但频繁更新容易造成性能抖动。
2. Sprite(精灵)
如果你想让粒子显示为图片(比如星星、雪花),可以用 Sprite。每个 Sprite 是一个始终面向摄像机的平面。
// 使用纹理的粒子
const map = new THREE.TextureLoader().load('star.png');
const material = new THREE.SpriteMaterial({
map: map,
blending: THREE.AdditiveBlending
});
const sprite = new THREE.Sprite(material);
sprite.position.set(0, 0, 0);
scene.add(sprite);
不过说实话,几百个 Sprite 还行,上千个就开始吃力了。我建议超过 2000 个粒子还是用 Points 方案。
3. 自定义着色器(进阶)
如果你想要更炫的效果——比如粒子大小随距离变化、颜色渐变、扭曲变形——那就得自己写着色器了。
这个我们后面章节会详细讲,这里先提一嘴:
- 顶点着色器控制粒子的位置和大小
- 片元着色器控制粒子的颜色和透明度
- 可以用纹理给粒子增加细节
避坑指南:我曾经在项目里直接用 PointsMaterial 做了一万个粒子,效果还行。后来客户要求加到五万个,帧率直接掉到 20fps。排查了半天,发现是材质里开了透明混合,而且每个粒子都单独计算了光照。关掉不必要的功能后,帧率回到了 60fps。
所以记住:粒子系统里,能关的功能就关掉。不需要光照就关掉 lighting,不需要深度测试就关掉 depthTest。
性能考量
做粒子系统,性能是绕不开的话题。我总结了几条经验:
- 合并几何体:所有粒子共用同一个 BufferGeometry,不要每个粒子单独创建
- 使用 BufferGeometry:比普通 Geometry 快得多
- 控制粒子数量:移动端建议不超过 10000,PC 端不超过 50000
- 关闭不必要的渲染特性:比如阴影、光照、雾效
- 使用 LOD:远处粒子可以变小或减少数量
一句话总结:粒子系统就是用「数量换效果」,但别忘了——数量上去了,性能就下来了。找到那个平衡点,才是真本事。
好了,这一章我们搞清楚了粒子系统是什么、能干什么、Three.js 里怎么用。下一章我会带大家手写一个完整的粒子星空效果,到时候咱们边写边聊。