基于three.js实现一个粒子系统(一)
这是一篇系列教程,在这篇教程里我将带领你一步步地实现一个基于three.js的webgl粒子系统Particle System。
粒子系统主要用来实现如:液体,光,烟雾,爆炸等视觉效果。借助大量的粒子之间的物理运动来模拟现实世界的视觉效果,每个粒子都被赋予了自己的生命周期,速度,加速度等参数,就像是一个训练有素的士兵根据系统发出的指令来完成自己的使命。
下图是我在blender中用内置的粒子系统实现的效果,通过大量的粒子实现液体撞击效果,看到这里你是不是对粒子有了一定的概念了呢。
我们知道通过大量的粒子运动可以模拟出很多物理效果,但这也增加了处理器的计算负担,导致帧率下降。为了给处理器减负,聪明的程序员发明了基于公告牌billboard技术的粒子系统,并在3D游戏中得到了广泛的应用,公告牌系统中每个粒子都是一个面向摄像机的平面贴图,这大大减少了需要计算的顶点数量,而且由于贴图始终面向摄像机,用户也不会有突兀感。
在three.js使用THREE.Sprite来创建面向摄像机的贴图,这次我们Sprite来创建一个简单的粒子效果场景。
先创建200个Sprite对象相对场景中心点旋转,你会看到这些粒子始终朝向摄像机,即使只是一个贴图也不会觉得有什么不自然。
_initParticles() {
this.particleGroup = new THREE.Group()
this.particleAttributes = {
startSize: [],
startPosition: [],
randomness: []
}
const particleNum = 200
const particleTex = new THREE.TextureLoader().load('img/spark.png')
for(let i = 0; i < particleNum; i++) {
const spriteMaterial = new THREE.SpriteMaterial({
map: particleTex,
color: 0xffffff,
blending: THREE.AdditiveBlending,
sizeAttenuation: true
})
const sprite = new THREE.Sprite(spriteMaterial)
sprite.scale.set(32, 32, 1)
sprite.position.set(
Math.random() - 0.5,
Math.random() - 0.5,
Math.random() - 0.5
)
sprite.position.setLength(this.params.radiusRange * (Math.random() * 0.2 +0.8))
sprite.material.color.setHSL(Math.random(), 0.9, 0.7)
sprite.material.opacity = 0.9
sprite.material.transparent = true
this.particleGroup.add(sprite)
this.particleAttributes.startPosition.push(sprite.position.clone())
this.particleAttributes.randomness.push(Math.random())
}
this.particleGroup.position.y = 50
this.scene.add(this.particleGroup)
}
点击下图可以在浏览器中查看效果,下次我们正式开始创建粒子系统,下次见!