1.概念介绍
2.参考案例
3.个人作品
一、概念介绍
简介:粒子系统表示三维计算机图形学中模拟一些特定的模糊现象的技术,而这些现象用其它传统的渲染技术难以实现的真实感的 game physics。经常使用粒子系统模拟的现象有火、爆炸、烟、水流、火花、落叶、云、雾、雪、尘、流星尾迹或者象发光轨迹这样的抽象视觉效果等等。 原理:很多细小的粒子从发射器中以一定的初速度和加速度进行向外发射。达到一定的生命周期时,会自己消失。而在整个粒子系统中,还有很多新的粒子会不断地产生。
二、参考案例
1.案例一:受力作用的粒子系统
简介 应用运动遵循牛顿第二定律原则F=M*A,同时将力的累加算法作用在粒子上,实现更好的模拟框架实现步骤 1.建立单个粒子类:初始化粒子速度,加速度,绘制粒子,更新位置 2.建立粒子系统类:初始化粒子系统,添加力,绘制粒子系统。 3.实现添加力的函数(思想是将力作用在粒子系统上,系统再将力作用在每个粒子上)代码展示
import java. util. Iterator;
ParticleSystem ps;
void setup ( ) {
size ( 400 , 400 ) ;
smooth ( ) ;
ps= new ParticleSystem ( new PVector ( width/ 2 , 50 ) ) ;
}
void draw ( ) {
background ( 0 ) ;
PVector gravity = new PVector ( 0 , 0.1 ) ;
ps. applyForce ( gravity) ;
ps. addParticles ( ) ;
ps. run ( ) ;
}
class ParticleSystem {
ArrayList< Particle> particles;
PVector origin;
ParticleSystem ( PVector location) {
origin= location. get ( ) ;
particles= new ArrayList < Particle> ( ) ;
}
void addParticles ( ) {
particles. add ( new Particle ( origin) ) ;
}
void applyForce ( PVector f) {
for ( Particle p: particles) {
p. applyForce ( f) ;
}
}
void run ( ) {
Iterator< Particle> it = particles. iterator ( ) ;
while ( it. hasNext ( ) ) {
Particle p= ( Particle) it. next ( ) ;
p. run ( ) ;
if ( p. isDead ( ) ) {
it. remove ( ) ;
}
}
}
}
class Particle {
PVector location;
PVector velocity;
PVector acceleration;
float lifespan;
float mass= 1 ;
Particle ( PVector L ) {
acceleration = new PVector ( 0 , 0 ) ;
velocity= new PVector ( random ( - 1 , 1 ) , random ( - 2 , 0 ) ) ;
location= L . get ( ) ;
lifespan= 255.0 ;
}
void run ( ) {
update ( ) ;
display ( ) ;
}
void applyForce ( PVector force) {
PVector f = force. get ( ) ;
f. div ( mass) ;
acceleration. add ( f) ;
}
void update ( ) {
velocity. add ( acceleration) ;
location. add ( velocity) ;
acceleration. mult ( 0 ) ;
lifespan-= 2.0 ;
}
void display ( ) {
stroke ( 255 , lifespan) ;
fill ( 255 , lifespan) ;
ellipse ( location. x, location. y, 8 , 8 ) ;
}
boolean isDead ( ) {
if ( lifespan< 0.0 ) {
return true ;
} else {
return false ;
}
}
}
效果展示
2.案例二:不同粒子的粒子系统
简介 在同一个发射器中,发射出不同的粒子,有各种形状,不同大小,不同颜色。思路 用多态实现粒子系统。使得新的粒子继承原始粒子,重新display(绘制粒子)的函数,最后通过父类引用指向子类对象进行函数的调用。力的作用和使用到的公式同上一个案例 拓展 原始案例中没有对每一个粒子的大小形状做出改变。在这里可以使用random函数随机生成粒子的大小和形状。同时将一个粒子系统拓展为多个粒子系统。粒子系统的位置也随机指定。同时加入鼠标的交互,点击鼠标时,改变粒子系统的位置。代码展示
import java. util. Iterator;
ParticleSystem[ ] ps= new ParticleSystem [ 5 ] ;
void setup ( ) {
size ( 800 , 400 ) ;
smooth ( ) ;
for ( int i= 0 ; i< 5 ; i++ ) {
ps[ i] = new ParticleSystem ( new PVector ( random ( 100 , width) , random ( 0 , 200 ) ) ) ;
}
}
void draw ( ) {
background ( 0 ) ;
PVector gravity = new PVector ( 0 , 0.1 ) ;
for ( int i= 0 ; i< 5 ; i++ ) {
ps[ i] . applyForce ( gravity) ;
ps[ i] . addParticles ( ) ;
ps[ i] . run ( ) ;
}
}
void mouseClicked ( ) {
for ( int i= 0 ; i< 5 ; i++ ) {
ps[ i] = new ParticleSystem ( new PVector ( random ( 100 , width) , random ( 0 , 200 ) ) ) ;
}
}
class Particle {
PVector location;
PVector velocity;
PVector acceleration;
float lifespan;
float mass= 1 ;
Particle ( PVector L ) {
acceleration = new PVector ( 0 , 0 ) ;
velocity= new PVector ( random ( - 1 , 1 ) , random ( - 2 , 0 ) ) ;
location= L . get ( ) ;
lifespan= 255.0 ;
}
void run ( ) {
update ( ) ;
display ( ) ;
}
void applyForce ( PVector force) {
PVector f = force. get ( ) ;
f. div ( mass) ;
acceleration. add ( f) ;
}
void update ( ) {
velocity. add ( acceleration) ;
location. add ( velocity) ;
acceleration. mult ( 0 ) ;
lifespan-= 2.0 ;
}
void display ( ) {
stroke ( random ( 125 , 255 ) , random ( 215 , 255 ) , random ( 0 , 255 ) , lifespan) ;
fill ( random ( 0 , 255 ) , random ( 0 , 255 ) , random ( 0 , 255 ) , lifespan) ;
ellipse ( location. x, location. y, random ( 0.5 , 15 ) , random ( 0.5 , 15 ) ) ;
}
boolean isDead ( ) {
if ( lifespan< 0.0 ) {
return true ;
} else {
return false ;
}
}
}
class Confetti extends Particle {
Confetti ( PVector L ) {
super ( L ) ;
}
void display ( ) {
float theta= map ( location. x, 0 , width, 0 , TWO_PI * 2 ) ;
rectMode ( CENTER ) ;
fill ( random ( 0 , 255 ) , random ( 0 , 255 ) , random ( 0 , 255 ) , lifespan) ;
stroke ( random ( 0 , 255 ) , random ( 0 , 255 ) , random ( 0 , 255 ) , lifespan) ;
rect ( location. x, location. y, random ( 0.5 , 15 ) , random ( 0.5 , 15 ) ) ;
}
}
class ParticleSystem {
ArrayList< Particle> particles;
PVector origin;
ParticleSystem ( PVector location) {
origin= location. get ( ) ;
particles= new ArrayList < Particle> ( ) ;
}
void addParticles ( ) {
float r= random ( 1 ) ;
if ( r< 0.5 ) {
particles. add ( new Particle ( origin) ) ;
} else {
particles. add ( new Confetti ( origin) ) ;
}
}
void applyForce ( PVector f) {
for ( Particle p : particles) {
p. applyForce ( f) ;
}
}
void run ( ) {
Iterator< Particle> it = particles. iterator ( ) ;
while ( it. hasNext ( ) ) {
Particle p= it. next ( ) ;
p. run ( ) ;
if ( p. isDead ( ) ) {
it. remove ( ) ;
}
}
}
}
效果展示
三、个人作品
作品一:飞舞的泡泡
简介 该作品用利用图像纹理来模拟泡泡在空中的飘动,同时也模拟火焰的效果。可以在两种效果之间进行切换步骤 1.导入图片:使用Pimage 2.为泡泡的漂浮设计规则:泡泡受到重力,浮力,空气阻力。但是整体有一个向上升的趋势。因此浮力大于空气阻力加重力。而在这里为了简化,可以把三个力合成为一个力,通过添加到粒子系统上进而添加给粒子系统中的每一个粒子。同时,泡泡也会收到风力的作用,而这里为了实现交互的话,将风力的方向与鼠标的位置关联在一起,可以实现鼠标所在之处,为泡泡所漂浮的方向。 重力:F=m*g 浮力:F浮=ρgV 阻力:f=umg 3.为火焰设计规则:火焰的话在泡泡的基础上减少一个空气阻力类的设计 代码展示
PImage img;
import java. util. Iterator;
ParticleSystem ps;
boolean flag= false ;
void setup ( ) {
size ( 800 , 400 ) ;
smooth ( ) ;
ps= new ParticleSystem ( new PVector ( width/ 2 , height) ) ;
img= loadImage ( "pao2.png" ) ;
}
void draw ( ) {
background ( 0 ) ;
float dx= map ( mouseX, 0 , width, - 0.2 , 0.2 ) ;
PVector wind= new PVector ( dx, 0 ) ;
PVector buoyancy= new PVector ( 0 , random ( - 0.2 , 0.2 ) ) ;
if ( ! flag) ps. applyForce ( buoyancy) ;
ps. applyForce ( wind) ;
ps. run ( ) ;
ps. addParticles ( ) ;
}
void mouseClicked ( ) {
if ( ! flag) {
flag= true ;
img= loadImage ( "fire5.png" ) ;
} else {
img= loadImage ( "pao2.png" ) ;
flag= false ;
}
}
class ParticleSystem {
ArrayList< Particle> particles;
PVector origin;
ParticleSystem ( PVector location) {
origin= location. get ( ) ;
particles= new ArrayList < Particle> ( ) ;
}
void addParticles ( ) {
particles. add ( new Particle ( origin) ) ;
}
void applyForce ( PVector f) {
for ( Particle p : particles) {
p. applyForce ( f) ;
}
}
void run ( ) {
Iterator< Particle> it = particles. iterator ( ) ;
while ( it. hasNext ( ) ) {
Particle p= ( Particle) it. next ( ) ;
p. run ( ) ;
if ( p. isDead ( ) ) {
it. remove ( ) ;
}
}
}
}
class Particle {
PVector location;
PVector velocity;
PVector acceleration;
float lifespan;
float mass= 1 ;
Particle ( PVector L ) {
acceleration = new PVector ( 0 , 0 ) ;
velocity= new PVector ( random ( - 1 , 1 ) , random ( - 8 , 0 ) ) ;
location= L . get ( ) ;
lifespan= 255.0 ;
}
void run ( ) {
update ( ) ;
display ( ) ;
}
void applyForce ( PVector force) {
PVector f = force. get ( ) ;
f. div ( mass) ;
acceleration. add ( f) ;
}
void update ( ) {
velocity. add ( acceleration) ;
location. add ( velocity) ;
acceleration. mult ( 0 ) ;
lifespan-= 2.0 ;
}
void display ( ) {
render ( ) ;
}
void render ( ) {
imageMode ( CENTER ) ;
tint ( 255 , lifespan) ;
image ( img, location. x, location. y) ;
}
boolean isDead ( ) {
if ( lifespan< 0.0 ) {
return true ;
} else {
return false ;
}
}
}
效果展示
作品二:破碎的人像
简介 鼠标互动可以切换图片,点击鼠标后所有的小方格将会破碎,并因重力作用而向下坠落。单个粒子是由rect构成,rect的参数由粒子系统进行传递,传递的是rgb的值,单个粒子的大小可以根据实际进行调整:如果希望看起来像马赛克效果,可以增加rect的大小,这里我将rect的大小设置为了1 效果展示 代码展示(核心)
ParticleSystem ps;
PImage photo;
int index= 1 ;
String pic[ ] = { "heben.jpg" , "heben1.jpg" , "heben2.jpg" , "heben3.jpg" } ;
void setup ( ) {
size ( 200 , 200 ) ;
photo = loadImage ( "heben.jpg" ) ;
photo. loadPixels ( ) ;
ps = new ParticleSystem ( 0 , 0 , 1 , photo) ;
}
void draw ( ) {
background ( 0 ) ;
ps. display ( ) ;
ps. update ( ) ;
}
void mouseClicked ( ) {
ps. shatter ( ) ;
}
void mouseWheel ( ) {
if ( index== 4 ) {
index= 0 ;
}
photo = loadImage ( pic[ index] ) ;
photo. loadPixels ( ) ;
ps = new ParticleSystem ( 0 , 0 , 1 , photo) ;
index++ ;
}