粒子系统
1基本介绍
(1)粒子系统
粒子系统表示三维计算机图形学中模拟一些特定的模糊现象的技术,而这些现象用其它传统的渲染技术难以实现真实感的物理运动规律。经常使用粒子系统模拟的现象有火、爆炸、烟、水流、火花、落叶、云、雾、雪、尘、流星尾迹等现象。
粒子系统是由单个粒子构成,通过定义单个粒子的行为,控制单个粒子的生成组成数组可以构建一个简单的粒子系统,
子系统中的作用
继承是指子类继承父类的非私有成员变量与方法,在子类中可以使用。
多态有三要素:1.要有继承关系 2.要有子类重写父类成员方法 3.要有父类数据类型引用至子类。
重写是子类重写父类的方法,相同的方法名,参数类型与返回类型。
在继承与多态的基础上,粒子系统的丰富度可以进一步提升,比如添加不同形状的粒子等。
(3)粒子系统图像纹理
在粒子系统中使用图像纹理往往会获得不一样的效果,例如下图是通过带有透明度的图像纹理实现烟雾效果。如果图像有一定的透明度(就像下面模拟烟效程序中用到的图像),Processing会使用alpha透明度混合算法将一定比例的背景像素和前景像素结合起来,混合比例根据alpha值确定。
2拓展与应用
(1)继承和多态实现粒子系统
基本单个粒子的行为:设置初始位置;更新位置,添加速度和加速度,向量加法计算粒子的新位置;显示,在粒子的位置显示圆形粒子;消亡,将粒子显示时的颜色作为判断粒子消亡的条件。
class Particle {
PVector position;
PVector velocity;
PVector acceleration;
float lifespan;
Particle(PVector l) {
acceleration = new PVector(0,0.05);
velocity = new PVector(random(-1,1),random(-2,0));
position = l.get();
lifespan = 255.0;
}
void run() {
update();
display();
}
// 更新粒子位置
void update() {
velocity.add(acceleration);
position.add(velocity);
lifespan -= 2.0;
}
// 显示
void display() {
stroke(0,lifespan);
strokeWeight(2);
fill(lifespan,0,0);
ellipse(position.x,position.y,8,8);
}
// 判断该粒子是否达到消亡条件
boolean isDead() {
if (lifespan < 0.0) {
return true;
} else {
return false;
}
}
}
继承和多态的应用:创建一种新的粒子,继承基本粒子的位置更新,重载显示,新的粒子与基本粒子运动方式相同;显示不同,新的粒子为三角形,并且角度会有一定调整。
// 重载显示
void display() {
rectMode(CENTER);
fill(lifespan,80,0);
stroke(0,lifespan);
strokeWeight(2);
pushMatrix();
translate(position.x,position.y);
float theta = map(position.x,0,width,0,TWO_PI*2);
rotate(theta);
triangle(0, 5, 10, 0, 10, 10);
popMatrix();
}
粒子系统:由圆形粒子和三角粒子组成,即上述两种基于多态的粒子,两种粒子位置更新方式相同,显示不同,在粒子系统中,两种粒子产生的概率相同。
//粒子系统1:散射粒子
class ParticleSystem {
ArrayList<Particle> particles;
ParticleSystem()
{
particles = new ArrayList<Particle>();
}
void addParticle(PVector origin)
{
float r = random(1);
if (r < 0.5) {
particles.add(new Particle(origin));
}
else {
particles.add(new Confetti(origin));
}
}
void run() {
for (int i = particles.size()-1; i >= 0; i--) {
Particle p = particles.get(i);
p.run();
if (p.isDead()) {
particles.remove(i);
}
}
}
}
(2)使用图像纹理的粒子系统并添加鼠标交互
单个粒子的行为:初始化位置、加速度、速度;更新位置,根据速度,加速度以及鼠标位置移动带来的里的影响更新位置;显示,粒子显示半透明图像纹理,鼠标点击决定选用蓝色图像或是白色图像;消亡,当粒子透明度为0时消亡。
class Particle2 {
PVector pos;
PVector vel;
PVector acc;
float lifespan;
PImage img;
PImage img2;
Particle2(PVector l,PImage img_,PImage img2_) {
acc = new PVector(0,0);
float vx = randomGaussian()*0.3;
float vy = randomGaussian()*0.3 - 1.0;
vel = new PVector(vx,vy);
pos = l.get();
lifespan = 100.0;
img = img_;
img2=img2_;
}
void run() {
update();
render();
}
// 将力作用于粒子(不考虑质量)
void applyForce(PVector f) {
acc.add(f);
}
// 更新粒子的位置
void update() {
vel.add(acc);
pos.add(vel);
lifespan -= 2.5;
acc.mult(0); // clear Acceleration
}
// 显示
void render() {
tint(255,lifespan);
if(mousePressed)
image(img2,pos.x-10,pos.y-10);
else
image(img,pos.x-10,pos.y-10);
}
// 粒子是否起作用
boolean isDead() {
if (lifespan <= 0.0) {
return true;
} else {
return false;
}
}
}
粒子系统:与第一种粒子系统类似,控制粒子的生成,注意鼠标的参与使得粒子系统要对粒子施加力的作用。
// 向系统中当前所有粒子添加力(鼠标控制左右)
void applyForce(PVector dir)
{
for (Particle2 p: particles)
{
p.applyForce(dir);
}
}
(3)综合应用
故事背景:太空中的火箭意外撞到了神秘星球,神秘星球的守护女神出现,并操控着神奇的魔法。
火箭由基本的形状构成,让火箭不断上升,碰到星球时触发守护女神时间。
将基于多态构成的粒子系统作为火箭的上升的尾气,除单个粒子位置更新以外,整个粒子系统的位置也会更新,随着火箭上升。
将使用图像纹理的粒子系统作为守护女神手中的魔法能量,鼠标位置控制粒子的方向趋势,鼠标点击控制粒子的颜色。