Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

WebGL(贰拾) 粒子系统

  粒子系统只是设计上的称呼,在程序中所谓的粒子系统只是一大堆放在CPU中计算的顶点数据而已。平时我们绘制物体都是把数据一次性放入显存中,然后让GPU来计算。而粒子由很多有自己属性的顶点组成,很多运算需要在CPU上完成,所以数据是动态数据的。
  由于这个效果需要绘制多个烟花对象,所以把烟花对象做成了构造器,我们直接从这个构造器开始看。
//创建烟花构造器
var Hanabi=function(px,py){
  //爆炸力场,用于计算移动
  this.forcefield=new Float32Array(Hanabi*1),
  //保存所有顶点坐标,用于绘制,默认值都为0
  this.position=new Float32Array(Hanabi*1),
  //颜色信息,用于调整整个烟花的颜色
  this.color=[Math.random(),Math.random(),Math.random()];
  //模型矩阵,用于整体移动
  this.mMatrix=[1,0,0,0, 0,1,0,0, 0,0,1,0, px,py,-20,1];
  //为所有顶点计算相应的爆炸力
  for(i=0;i<Hanabi;i+=3){
    var a,b,l,r,x,y,z;
    //以0.15的半径随机产生爆炸方向和速度,也就是随机产生球体内坐标
    b=Math.random()*Math.PI*2,a=Math.acos(1-2*Math.random()),
    l=Math.sin(a),y=Math.cos(a),x=Math.sin(b)*l,z=Math.cos(b)*l;
    r=Math.random()*0.15;
    this.forcefield[i]=x*r,
    this.forcefield[i+1]=y*r,
    this.forcefield[i+2]=z*r;
  };
};
//定义每个烟花的顶点数为10000个
Hanabi.valueOf=function(){return 10000*3};
Hanabi.prototype={
  v:0, //重力初速度
  g:0.005, //重力加速度
  a:1, //生存期(透明度)
  draw:function(){ //绘制
    //计算重力速度并消耗生存期
    this.v+=this.g,this.a-=0.02;
    //遍历顶点,根据爆炸力场计算顶点位置,并附上重力的影响
    for(var i=0;i<Hanabi;i+=3){
      this.position[i]+=this.forcefield[i],
      this.position[i+1]+=this.forcefield[i+1]-this.v,
      this.position[i+2]+=this.forcefield[i+2];
    };
    //设置通用属性
    webgl.uniform1f(opacity,this.a); //透明度
    webgl.uniform3fv(color,this.color); //颜色
    webgl.uniformMatrix4fv(mMatrix,false,this.mMatrix); //位置
    //设置顶点数据(把内存中的数据放入显存)
    webgl.bindBuffer(webgl.ARRAY_BUFFER,positionBuffer);
    webgl.bufferData(webgl.ARRAY_BUFFER,this.position,webgl.STATIC_DRAW);
    //绘制顶点
    webgl.drawArrays(webgl.POINTS,0,Hanabi/3);
  }
};
  每一个实例都是一个烟花对象,都有自己的位置和形状。所以每个烟花对象的顶点数据本身就是不同的,需要每次绘制时从内存传入。所以我们在内存中直接使用了Float32Array这个强类型数组。它在内存中是连续的,需要时可以直接从头指针开始复制,省去一大堆不必要的运算。爆炸力场的计算其实就是用了上一篇的“球面随机坐标”,加上一个随机的半径构成的。烟花爆炸时,每一个碎片都有自己不同的飞行方向和初速度,所以它是一个向量场。这里我就不计算空气阻力什么的麻烦的东西了,只是做简单的模拟而已。
  其它代码都是之前的文章说过的知识而已,我就不再说了。直接看最终的完整实例吧

  WebGL粒子系统
网名:
34.203.245.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^