最近在做基于away3D引擎的粒子编辑器,因此,有了这部分文章作为mark。
Away3D从4.1alpha之后开始加入了粒子系统功能,再次感谢国内牛人LiaoCheng,是他向away3d贡献的这部分功能,大家鼓掌。
简介
所谓粒子系统是表示三维计算机图形学中模拟一些特定的模糊现象的技术,游戏开发中经常使用粒子系统模拟的现象有火、爆炸、烟、水流、火花、落叶、云、雾、雪、尘、流星尾迹或者像发光轨迹这样的抽象视觉效果等等。
Away3D中的粒子系统实现思路
跟大部分游戏的引擎的粒子系统实现思路类似,Away3D的粒子系统遵循以下基本原则:
- 每个粒子由带纹理的多边形或几何体构成;
- 粒子按一定的规则运动;
- 每个粒子有自己的属性,如出生时间、生命周期、位置、速度、加速度、尺寸、颜色、运动轨迹等等;
粒子生成步骤
在Away3D中,由n个粒子组成的粒子特效(为了与广泛的粒子系统区分,我们下面都称为粒子特效)主体,被抽象为一个mesh,而mesh的材质就是给粒子添加的材质,再往mesh中添加animator就组成了一个完整的粒子特效。下面我们就如何构建一个粒子mesh,以及如何为mesh添加动作器展开分析。
构建ParticleGeometry
在上面的的粒子系统基本思路说过:每个粒子由带纹理的多边形或几何体构成,而组成一个完整的粒子特效,则需要n个这样的多边形或几何体,这边我们且称为Geometry Set,我们可以往这个geometry set添加各种Away3D内置的几何体或者外部定义的几何体。出于性能的考虑,建议粒子特效里边最好不要添加太复杂的几何体。
举一个简单的栗子,我们要构建一个向上喷发的小球,就可以如下构建该粒子特效:
var ball:Geometry = new PlaneGeometry(3,3,1,1,false); var ballGeoSet:Vector.<Geometry> = new Vector.<Geometry>(); // particle ball for (var i:int = 0; i < 50; i++) { ballGeoSet.push(ball); }
上面的代码,我们添加了包含50个Plane的geometry set,填充这个set可以视情况添加,如果有需要,你也可以同时添加plane、cube、sphere等几何体到这个set里边。准备好geometry set后,我们将使用Away3D提供的particle geometry helper将geometry set转化为最终的ParticleGeometry:
particleGeometry = ParticleGeometryHelper.generateGeometry(ballGeoSet);
这样,我们就完成的一个尚未添加动作的ParticleGeometry实例。
构建ParticleAnimationSet
接下来就是创建粒子动作集合了。类似传统的粒子系统,一个粒子是有其生命周期的,在这个周期中,粒子控制着它所有的属性,位置、轨迹等等。
在Away3D中,一个粒子有关联系统时间的startTime属性,代表粒子出生时间;有可选的duration属性(若没设置duration属性,粒子将无限延续),代表粒子的持续存活时间,还有可选的delay属性(若没设置,将无间隔时间),代表两个重复的粒子周期之间的间隔时间。这些属性基于GPU代码的时间计算,我们必须对要使用的属性进行预定义。
Away3D粒子系统中为粒子动作提供了动作集合ParticleAnimationSet类,构造ParticleAnimationSet需要三个bool参数,第一个参数表示是否使用粒子的duration属性,第二个表示是否不断循环粒子的生命周期,第三个表示是否使用粒子的delay属性,使用则当一个粒子周期执行完成,粒子会消失delay的时间后再进行新的周期。
还是上面的栗子,我们把三个属性都设置为true。
var animationSet:ParticleAnimationSet = new ParticleAnimationSet(true, true, true); animationSet.initParticleFunc = initParticleParam;
值得注意的是,startTime、duration、delay并不是ParticleAnimationSet的属性,粒子特效中的每个粒子都有自己特有的以上三个属性,在Away3D中,他们被设定为local static属性,我们使用一个函数来定义以上的属性,然后赋给ParticleAnimationSet的initParticleFunc,这样,每个粒子都会调用这个函数一遍。通常,使用ParticleProperties::index这个值设置startTime、duration、delay三个属性,达到每个粒子有不同的以上属性的目的。栗子如下:
private function initParticleParam(prop:ParticleProperties):void { prop.startTime = prop.index * 0.005; prop.duration = 10; prop.delay = 5; }
以上代码中,我们实现了每5毫秒产生一个粒子,每个粒子延续10秒,然后休眠5秒。
在之后的local static动作属性的设置中,我们也将所用动作的属性设置添加到这个独立的函数中。