13 Babylonjs基础入门 粒子

创建粒子

本教程将讨论Babylon.js中的粒子系统。粒子通常是小型的精灵,用于模拟难以再现的现象,如火,烟,水,或抽象的视觉效果,如魔法闪光和技能特效。这是通过一个区域发出很多粒子组成的云来完成的。从V3.2版本开始,有特定的发射器将该区域约束为一个盒子、球体或圆锥体的形状。你还可以编写自己的自定义函数来控制粒子云和约束区域。
GPU粒子是粒子系列的最新成员,可以使用适当的浏览器来提高性能。
在这里插入图片描述
点击查看粒子系统

粒子系统

要实现这一个神奇的效果,首先需要创建粒子系统ParticleSystem对象。

var particleSystem = new BABYLON.ParticleSystem("particles", 2000, scene);

创建时需要设置粒子的总量。粒子系统还设置纹理以便在粒子上查看和发射器设置粒子的起始点和扩散方式。
请注意你可以使用ParticleHelper来创建一个默认的配置:

BABYLON.ParticleHelper.CreateDefault(emitter);

完成后,使用粒子系统启动:

particleSystem.start();

停止:

particleSystem.stop();

要延迟粒子系统启动,可以设置particleSystem.startDelay = 3000;定义延迟(以毫秒为单位)。
你也可以设置particleSystem.start(3000);在启动时设置延迟。如果当前设置,当前值将会覆盖particleSystem.startDelay的值。
注意:停止粒子系统将会停止创建新的粒子,但是已经创建的粒子将会继续运行。如果要清空粒子,则需要调用particleSystem.reset()
如果你需要设置粒子系统的运行时间,并且后面可能还会继续运行系统:

particleSystem.targetStopDuration = 5;  //五秒后粒子效果会停止

运行一次就销毁掉,你可以调用粒子系统的particleSystem.dispose()方法。这对于制作射击粒子系统是非常有用的。

particleSystem.disposeOnStop = true;  //粒子效果停止后销毁粒子系统

预运行

从Babylon.js v3.3版本开始,你可以设置粒子提前运行,以确保在显示之前达到预期显示的效果。
为此,你需要设置两个属性:

  • system.preWarmCycles: 获取或设置一个值,设置在首次渲染之前提前执行多少帧(必须在启动系统之前设置此值)。默认值为0
  • system.preWarmStepOffset:获取或设置一个值,指在预启动模式下时每一帧运行的速度和默认速度比。(默认值为1)
    因此,你将系统设置为:
system.preWarmCycles = 100;
system.preWarmStepOffset = 5;
system.start();

它设置将在运行前提前运行100帧,并且每一帧的运算为原来的五倍。如果你要提前运行的周期越长,系统程序启动的越慢。虽然减少运行周期增加每一帧的运行率很有趣。但是记住,如果粒子的生命周期小于单帧运行的帧率,那么将会出现问题。
以下是一个提前启动运行的案例:点击这里

粒子纹理

将纹理图片应用于粒子,例如:
在这里插入图片描述
设置particleTexture:

particleSystem.particleTexture = new BABYLON.Texture("PATH TO IMAGE", scene);

你还可以将蒙版应用于纹理以过滤某些颜色,或过滤透明通道的一部分

particleSystem.textureMask = new BABYLON.Color4(0.1, 0.8, 0.8, 1.0);

将产生以下效果:
在这里插入图片描述
要在场景中使用多个纹理,请使用多个粒子系统,所有粒子系统都可以使用相同的发射器对象。

粒子发射器

粒子发射器可以受用三维向量或者模型网格定位,在这种情况下,网格的位置用于定位。

particleSystem.emitter = new BABYLON.Vector3(-1, 2, 3);
var source = BABYLON.Mesh.CreateBox("source", 1.0, scene);
particleSystem.emitter = source;

世界偏移量

从Babylon.js v4.0开始,你可以使用以下方法设置粒子的世界偏移量:

particleSystem.worldOffset = new BABYLON.Vector3(100, 20, -453);

此代码使用世界偏移移动粒子(当你的相机需要保持在世界坐标的原点以提高精度,然后移动世界坐标时)。

粒子扩散和位置

粒子的扩散来至于我们定义的一个盒子,盒子的位置是相对于发射器的位置。发射器的盒子需要知道六个面的位置,这里我们只需要知道盒子的最大点和最小点既可以设置出发射器的扩散位置,即设置粒子系统的minEmitBox和完成的maxEmitBox:

particleSystem.minEmitBox = new BABYLON.Vector3(-2, -3, 4); 
particleSystem.maxEmitBox = new BABYLON.Vector3(4, 2, 3);

盒子可以压缩成一条线,例如x轴:
在这里插入图片描述

particleSystem.minEmitBox = new BABYLON.Vector3(-1, 0, 0); 
particleSystem.maxEmitBox = new BABYLON.Vector3(1, 0, 0);

基础的粒子案例

你可以查看下面两个案例,创建了一个普通的粒子系统,尽管很普通。只有一些粒子出现并扩散到空中消失。
小区域粒子示例
大区域粒子示例
但是,通过我们设置其它属性,很快将粒子变得特别的有趣。

调整粒子系统

下面,我们将了解如何修改粒子的生命周期,大小和颜色,粒子发射器的产生粒子速度,方向(可选是否受重力影响)。你还可以修改它们的旋转,速度和形状。你可以在下面找到修改其参数的配置。

生命周期

一个单独的粒子的生命周期是在产生后到消失(或死亡)所花费的时间。一旦粒子死掉,粒子就会被回收。它的寿命可以通过配置一下两个配置,并从里面随机一个时间作为存活时间:

//存活时间从最小到最大值中间取一个随机时间
particleSystem.minLifeTime = 0.3;
particleSystem.maxLifeTime = 1.5;

从Babylon.js v3.3版本开始,你还可以为有声明周期的粒子系统定义它的粒子的生命周期。比如,如果你设置粒子系统的生命周期为particleSystem.targetStopDuration = 5; 就是粒子系统的生命周期为5秒,那么你可以:

particleSystem.addLifeTimeGradient(0, 0.5);
particleSystem.addLifeTimeGradient(1, 0);

addLifeTimeGradient()方法的第一个参数定义了粒子在粒子系统生命周期出现的时间(0为粒子系统启动时间,1为粒子系统结束时间)。第二个参数是粒子的存活时间。
上面分别设置了粒子在粒子系统开始时的存活时间为0.5秒,而如果在结束时出现,则存活时间接近0秒。
建议至少要为开始和结束设置一个粒子的存活时间。
只要渐变值介于0到1之间,就可以根据需要添加任意渐变。
你还可以通过为每个渐变增加第三个值来定义更复杂的渐变:

particleSystem.addLifeTimeGradient(0, 0.5, 0.8);
particleSystem.addLifeTimeGradient(1.0, 0, 0.1);

在这种情况下,第一个值还是定义了处于粒子系统存活的时间段,后两个值代表粒子将会在两个值中间随机一个粒子的寿命。
要删除某个渐变,你可以调用particleSystem.removeLifeTimeGradient(0.5)

粒子大小

粒子的大小也可以通过设定范围,并在范围内随机生成:

// 设置大小的最大值和最小值
particleSystem.minSize = 0.1;
particleSystem.maxSize = 0.5;

如果将粒子修改为长方形,而不是必须为正方形,则可以使用ScaleX/Y来设置最大值和最小值:

particleSystem.minScaleX = 0.1;
particleSystem.maxScaleX = 0.5;

particleSystem.minScaleY = 0.2;
particleSystem.maxScaleY = 0.4;

从Babylon.js v3.3版本开始,你还可以定义粒子系统生命周期内的粒子大小渐变。
要添加大小渐变,请使用以下代码:

particleSystem.addSizeGradient(0, 0.5);

第一个参数定义了粒子的某个时间点(0代表粒子生成时,1代表粒子消失时间)。第二个参数是粒子处于当前时间时的大小。当前的设置,是粒子产生的初始大小为设置的随机出来的大小的一半(从minScale和maxScale计算)。建议至少为0和1(开始和结束)定义一个渐变:

particleSystem.addSizeGradient(0, 0.5);
particleSystem.addSizeGradient(1.0, 3);

只要渐变值介于0和1之间,就可以根据需要添加任意渐变。
你还可以通过提供第三个值来定义更复杂的渐变:

particleSystem.addSizeGradient(0, 0.5, 0.8);
particleSystem.addSizeGradient(1.0, 3, 4);

在这种情况下,大小缩放会从第二个值和第三个值中间随机一个值来设置粒子大小缩放。
要删除渐变,你可以调用particleSystem.removeSizeGradient(0.5)
处理粒子大小时,你可能需要移动变换中心。默认情况下,变换中心为粒子的中心,如果你需要在粒子的顶部或者底部。值需要调用:

particleSystem.translationPivot = new BABYLON.Vector2(0, -0.5); //这个的变换中心在粒子的底部

下面是一个将变换中心移动到底部的一个案例:冒烟的效果

粒子颜色

可以为粒子设置三种颜色,两种颜色在粒子的生命周期内混合生成,第三种颜色会在粒子消失之前生成。

particleSystem.color1 = new BABYLON.Color4(0.7, 0.8, 1.0, 1.0);
particleSystem.color2 = new BABYLON.Color4(0.2, 0.5, 1.0, 1.0);
particleSystem.colorDead = new BABYLON.Color4(0, 0, 0.2, 0.0);

从Babylon.js v3.3版本开始,你还可以定义颜色的渐变。如果定义颜色的渐变,则将忽略掉color1,color2和colorDead属性。
要添加颜色渐变,请调用以下代码:

particleSystem.addColorGradient(0, new BABYLON.Color4(1, 1, 1, 0));

第一个参数定义了粒子的某个时间点(0代表粒子生成时,1代表粒子消失时间)。第二个参数是粒子处于当前时间时的颜色。

particleSystem.addColorGradient(0, new BABYLON.Color4(1, 1, 1, 0));
particleSystem.addColorGradient(1.0, new BABYLON.Color4(1, 1, 1, 1));

只要渐变值介于0和1之间,就可以根据需要添加任意渐变。
你还可以通过设置第三个值的一个颜色来定义更复杂的渐变:

particleSystem.addColorGradient(0, new BABYLON.Color4(1, 1, 1, 0), new BABYLON.Color4(1, 0, 1, 0));
particleSystem.addColorGradient(1.0, new BABYLON.Color4(1, 1, 1, 1)new BABYLON.Color4(1, 0, 1, 1));

这种情况下,当到达相应的梯度时,粒子颜色将会从两个颜色中间随机出来一个颜色。
要删除一个设置的渐变,你可以调用particleSystem.removeColorGradient(0.5)
一下是颜色渐变的案例:太阳特效

粒子混合

粒子和场景混合的方式有多重,我们通过设置粒子系统的blendMode属性:

particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;
particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_STANDARD;

BLENDMODE_ONEONE是默认值,如果没有手动设置,blendMode的值将会是这个。其它可设置的值是:

  • BLENDMODE_ONEONE - 设置颜色不会影响到粒子的alpha(透明部分)
  • BLENDMODE_STANDARD- 使用粒子的alpha(即颜色(1-alpha)+ particleColor alpha)添加颜色。
  • BLENDMODE_ADD - 添加颜色,但只有粒子颜色使用粒子的alpha(即color + particleColor * alpha)。
  • BLENDMODE_MULTIPLY - 颜色相乘并添加到(1 - alpha)(即color * particleColor + 1 - alpha)点击查看案例
  • BLENDMODE_MULTIPLYADD- 用两个渲染BLENDMODE_MULTIPLY然后渲染BLENDMODE_ADD。点击查看案例

粒子产生速率

我们可以通过设置emitRate粒子每秒的产生量。设置的数值越大,发出的粒子云就密集。当单个粒子消失时,它会再次被加入循环中被生成。如果它们存在时间够长,而且设置的产生速率过快,粒子产生可能会出现间歇期。
在这里插入图片描述

particleSystem.emitRate = 1000;

你可以通过设置手动发射计数来停止连续发射粒子

particleSystem.manualEmitCount = 300;

如果产生的粒子到达设置的数量时,粒子将停止产生。

粒子方向

粒子可以设置两个方向。如果仅设置了一个方向,粒子会沿这个方向随机一个方向移动。如果设置了两个方向,粒子通常会在两个方向值范围内随机。

particleSystem.direction1 = new BABYLON.Vector3(-7, 8, 3);
particleSystem.direction2 = new BABYLON.Vector3(7, 8, -3);

方向也会受重力影响。

重力

可以设置粒子应用重力。例如,如果设置Y轴上面一个负值,粒子会有缓慢下降的效果。

particleSystem.gravity = new BABYLON.Vector3(0, -9.81, 0);

旋转

你可以为粒子设置一个绕Z轴旋转速度,以弧度/秒为单位:

particleSystem.minAngularSpeed = 0;
particleSystem.maxAngularSpeed = Math.PI;

你还可以通过以下方法设置粒子随机初始旋转角度的范围:

particleSystem.minInitialRotation = 0;
particleSystem.maxInitialRotation = Math.PI;

从Babylon.js v3.3版本开始,你还可以定义旋转速度的渐变。
要设置粒子旋转速度变化,请使用以下方法:

particleSystem.addAngularSpeedGradient(0, 0.5);

第一个参数是粒子的相应时间阶段(0代表为粒子产生时,1代表粒子消失时)。第二个参数是要设置的旋转速度。在上面设置情况下,粒子产生后将以每帧0.5弧度的速度旋转。建议至少为0和1设置一个渐变值:

particleSystem.addAngularSpeedGradient(0, 0.5);
particleSystem.addAngularSpeedGradient(1.0, 3);

只要渐变值处于0到1之间,就可以根据需要添加任意的渐变。
你也可以通过给渐变设置两个旋转速度,让粒子从中随机一个旋转速度:

particleSystem.addAngularSpeedGradient(0, 0.5, 0.8);
particleSystem.addAngularSpeedGradient(1.0, 3, 4);

在这种情况下,到达当前阶段时,粒子会从两个值中间随机出一个旋转速度。
要删除渐变,您可以调用particleSystem.removeAngularSpeedGradient(0.5)

速度

你可以定义粒子的产生的功率范围,以及粒子运动速度(0.01是默认的速度,值越大则速度约快)。

particleSystem.minEmitPower = 1;
particleSystem.maxEmitPower = 3;
particleSystem.updateSpeed = 0.005;

随着时间而改变的速度

你可以通过渐变定义速度随时间的变化。速度随时间的变化是应用于粒子方向的。如果值为2,则实际速度将是原来的两倍。
要添加速度渐变,请通过以下方式:

particleSystem.addVelocityGradient(0, 0.5);

第一个参数定义的时间段(0为粒子产生时间,1为粒子消失时间)。第二个参数是要使用的速度。上一段设置意思为粒子生成时的速度为默认的0.5 。建议至少为0和1定义一个渐变:

particleSystem.addVelocityGradient(0, 0.5);
particleSystem.addVelocityGradient(1.0, 3);

只要渐变值处于0到1之间,就可以根据需要添加任意的渐变。
你也可以通过给渐变设置两个速度,让粒子从中随机一个速度:

particleSystem.addVelocityGradient(0, 0.5, 0.8);
particleSystem.addVelocityGradient(1.0, 3, 4);

这种情况下,粒子到达相应的阶段,将从后两个值范围内随机一个速度。
一下是粒子系统的速度案例:点击这里
要删除某个阶段渐变,你可以调用particleSystem.removeVelocityGradient(0.5)

限制粒子极限速度

由于设置的速度是一个加速度,因此速度会不断叠加,当前配置可以限制粒子的极限速度。如果需要设置整体的极限速度,你可以配置particleSystem.limitVelocityDamping
如果你需要添加极限速度的渐变,可以这样配置:

particleSystem.addLimitVelocityGradient(0, 0.5);

第一个参数为当前阶段(0为粒子产生时,1为粒子消失时)。第二个参数为粒子的极限速度。在这种情况下,粒子在产生以后就会直接检测当前速度,如果大于极限速度,则会应用阻尼参数(实际速度乘以阻尼值得到的结果)。建议至少为0和1定义一个渐变:

particleSystem.addLimitVelocityGradient(0, 0.5);
particleSystem.addLimitVelocityGradient(1.0, 3);

只要渐变值处于0到1之间,就可以根据需要添加任意的渐变。
你还可以通过设置两个极限速度实现更复杂的需求:

particleSystem.addLimitVelocityGradient(0, 0.5, 0.8);
particleSystem.addLimitVelocityGradient(1.0, 3, 4);

这种情况下,如果到达当前阶段,将在两个值的范围内随机一个极限速度。点击此处查看官方案例
要删除渐变,您可以调用particleSystem.removeLimitVelocityGradient(0.5)

阻力渐变

你可以设置随着时间改变的阻力渐变。改设置将用于向粒子移动方向施加阻力来模拟空气摩擦。例如,如果你的阻力系数设置为0.8,那粒子只能移动默认的20%的距离。
添加阻力渐变,请通过下面方式设置:

particleSystem.addDragGradient(0, 0.5);

第一个参数为当前阶段(0为粒子产生时,1为粒子消失时)。第二个参数是当前阶段施加的阻力。在这种情况下,粒子的位置将是particle.position = particle.direction * (1.0 - 0.5) 粒子的位置等于粒子的方向乘以1-阻力。建议至少为0和1定义一个渐变:

particleSystem.addDragGradient(0, 0.5);
particleSystem.addDragGradient(1.0, 3);

只要渐变介于0到1之间,就可以根据需要添加任意渐变。
你还可以通过为每一个渐变设置两个阻力值来实现更复杂的渐变:

particleSystem.addDragGradient(0, 0.5, 0.8);
particleSystem.addDragGradient(1.0, 0, 0.1);

这种情况下,当到达当前阶段时,粒子将在两个值范围内随机一个阻力值。
以下是设置阻力的案例:点击这里
要删除渐变,您可以调用particleSystem.removeDragGradient(0.5)

粒子产生的渐变

你可以通过使用渐变设置粒子产生速度。随着时间的推移,设置的值将覆盖system.emitRate(个数/秒)属性的值。
要添加粒子产生的渐变,请调用以下代码:

particleSystem.addEmitRateGradient(0, 10);

注意,只有粒子系统定义明确的生命周期(设置system.targetStopDuration)后,产生率的渐变才会生效。

第一个参数为粒子系统阶段(0为粒子产生时,1为粒子消失时)。第二个参数是当前阶段生成速度。在上面的设置,系统将每帧产生10个粒子。建议至少为0和1定义一个渐变:

particleSystem.addEmitRateGradient(0, 10);
particleSystem.addEmitRateGradient(1.0, 500);

只要渐变介于0到1之间,就可以根据需要添加任意渐变。
你还可以通过为每一个渐变设置两个值来实现更复杂的渐变:

particleSystem.addEmitRateGradient(0, 5, 10);
particleSystem.addEmitRateGradient(1.0, 800, 1000);

这种情况下,当到达当前阶段时,粒子将在两个值范围内随机一个产生速度。
以下是粒子系统的产生率渐变的案例:点击这里
要删除渐变,您可以调用particleSystem.removeEmitRateGradient(0.5)

粒子系统设置粒子大小渐变

要设置粒子大小随粒子系统的时间的渐变,请通过以下设置:

particleSystem.addStartSizeGradient(0, 2);

注意,只有粒子系统定义明确的生命周期(设置system.targetStopDuration)后,粒子大小的渐变才会生效。

第一个参数为粒子系统阶段(0为粒子产生时,1为粒子消失时)。第二个参数是当前粒子系统阶段粒子的大小。上面的设置系统会将粒子的大小改为原来的2倍。(比如,如果设置渐变为2,粒子初始大小设置为3,最终结果将是6)。建议至少为0和1定义一个渐变:

particleSystem.addStartSizeGradient(0, 10);
particleSystem.addStartSizeGradient(1.0, 500);

只要渐变介于0到1之间,就可以根据需要添加任意渐变。
你还可以通过为每一个渐变设置两个值来实现更复杂的渐变:

particleSystem.addStartSizeGradient(0, 5, 10);
particleSystem.addStartSizeGradient(1.0, 800, 1000);

这种情况下,当到达当前阶段时,粒子将在两个值范围内随机一个大小尺寸。
一下是粒子系统设置大小渐变的案例:点击这里
要删除渐变,您可以调用particleSystem.removeStartSizeGradient(0.5)

透明度渐变色

你可以使用这个渐变来根据透明度来修改粒子的颜色。
透明度渐变非常强大,但需要一些设置。
首先,你需要设置渐变颜色:

system.addRampGradient(0.0, new BABYLON.Color3(1, 1, 1));
system.addRampGradient(0.09, new BABYLON.Color3(209/255, 204/255, 15/255));
system.addRampGradient(0.18, new BABYLON.Color3(221/255, 120/255, 14/255));
system.addRampGradient(0.28, new BABYLON.Color3(200/255, 43/255, 18/255));
system.addRampGradient(0.47, new BABYLON.Color3(115/255, 22/255, 15/255));
system.addRampGradient(0.88, new BABYLON.Color3(14/255, 14/255, 14/255));
system.addRampGradient(1.0, new BABYLON.Color3(14/255, 14/255, 14/255));

第一个值为当前透明度的索引,第二个值是当前透明度时使用的颜色。这些颜色将用于生成渐变的颜色。
然后你需要设置使用它们:

system.useRampGradients = true;

通过粒子的透明度(通过计算textureAlpha 纹理透明度 * particleColorAlpha 粒子颜色透明度)来获取当前的实际显示透明度渐变色(透明度会作为从前面设置的渐变的索引去获取颜色)。获取到透明度渐变里面的颜色以后,将通过以下公式获取到最终显示的颜色:finalColor = textureColor * particleColor * rampColor[alphaIndex](最终颜色等于纹理颜色乘以粒子颜色再乘以获取到透明度索引到的渐变的颜色)。
为了实现更多的控制,你可以使用remap 重映射函数来重新定义这个透明度的索引:

system.addColorRemapGradient(0, 0, 0.1);
system.addColorRemapGradient(0.2, 0.1, 0.8);
system.addColorRemapGradient(0.3, 0.2, 0.85);
system.addColorRemapGradient(0.35, 0.4, 0.85);
system.addColorRemapGradient(0.4, 0.5, 0.9);
system.addColorRemapGradient(0.5, 0.95, 1.0);
system.addColorRemapGradient(1.0, 0.95, 1.0);

颜色重新映射渐变定义了随着时间的变化的透明度的最小值和最大值。然后使用下面的公式将alpha(透明度索引)从[min, max]重新映射到[0,1], finalAlphaIndex = clamp((alphaIndex - min) / (max - min), 0.0, 1.0) (最终的透明度索引将是透明度减去最小值,然后再除以最大值减去最小值的值。这个值的取值范围为0到1,如果这个值小于0,则被设置为0,如果这个值大于1,将被设置为1)。

你还可以通过重新映射来设置粒子每一个像素的透明度的值:

system.addAlphaRemapGradient(0, 0, 0.1);
system.addAlphaRemapGradient(1.0, 0.1, 0.8);

透明度的重新映射将使用以下公式计算最终的透明度的值:finalAlpha = clamp((textureAlpha * particleColorAlpha * rampColor.a - min) / (max - min), 0.0, 1.0)(最终的透明值等于纹理透明度乘以粒子颜色透明度再乘以透明度渐变的透明度减去最小的值除以最大值减去最小值的值。这个值的取值范围为0到1,如果这个值小于0,则被设置为0,如果这个值大于1,将被设置为1)。
我们可以在这里找到一个案例,通过按下空格键查看,案例加载速度比较慢,请耐心等待:点击这里

对准

默认情况下,所有的粒子都显示为广告牌(一直朝向与相机)。但是你可以通过设置粒子系统system.isBillboardBased = false将粒子的朝向与它们的方向对准。
在这里,你可以找到一个演示:点击这里

启用了广告牌效果后,你还可以决定是否要使用完整的效果(在所有的坐标轴上),还是仅仅在Y轴上:

system.billboardMode = BABYLON.ParticleSystem.BILLBOARDMODE_Y;

你还可以设置BILLBOARDMODE_STRETCHED,它将像一个完整的广告牌模式,但具有一个额外的旋转,这个旋转用于对准它们的朝向。
演示比语言更好的解释,我们来查看BILLBOARDMODE_Y的案例:点击这里
关于BILLBOARDMODE_STRETCHED的案例,请点击这里

可以实时调节的粒子案例

设置粒子发射器的形状

从Babylon.js v3.2版本开始,通过设置特定的配置,你可以将粒子产生区域塑造成一个

  • 点形状
  • 盒子形状
  • 球体形状
  • 半球形状
  • 圆柱形状
  • 锥体形状

点形状

要创建点形状的粒子发射器,你可以运行以下代码:

var pointEmitter = particleSystem.createPointEmitter(new BABYLON.Vector3(-7, 8, 3), new BABYLON.Vector3(7, 8, -3));

该createPointEmitter方法接收两个参数:

  • direction1:Vector3
  • direction2:Vector3
    粒子将从一个点,沿着设置的两个方向之间随机发射。
    通过返回的pointEmitter对象,我们也可以动态修改这些值:
pointEmitter.direction1 = new BABYLON.Vector3(-5, 2, 1); 
pointEmitter.direction2 = new BABYLON.Vector3(5, 2, 1);

盒子形状

如果想创建一个盒子形状的发射器

var boxEmitter = particleSystem.createBoxEmitter(new BABYLON.Vector3(-7, 8, 3), new BABYLON.Vector3(7, 8, -3), new BABYLON.Vector3(-1, 0, 0), new BABYLON.Vector3(1, 0, 0));

createBoxEmitter方法按以下顺序采用四个参数

  • direction1:Vector3, - 第一个方向
  • direction2:Vector3, - 第二个方向
  • minEmitBox:Vector3,- 盒子的最小值
  • maxEmitBox:Vector3 - 盒子的最大值
    返回的boxEmitter对象可用于更改这些属性的值。
boxEmitter.direction1 = new BABYLON.Vector3(-5, 2, 1); 
boxEmitter.direction2 = new BABYLON.Vector3(5, 2, 1);  
boxEmitter.minEmitBox = new BABYLON.Vector3(-2, -3, -4);  
boxEmitter.maxEmitBox = new BABYLON.Vector3(2, 3, 4);

球型发射器

你可以创建可以设置球的半径的发射器,比如半径为1.2:

var sphereEmitter = particleSystem.createSphereEmitter(1.2);

我们还可以通过返回的sphereEmitter 动态修改半径。
粒子会在球的内部区域随机一个产生位置,并且沿着当球心到产生位置的方向移动。

你还可以设置sphereEmitter.radiusRange属性是沿表面还是在球内。如果值为0,表示随机在球的表面,如果值为1,则在球内随机产生。
如果你需要设置粒子的方向,则可以创建定向球发射器:

var sphereEmitter = particleSystem.createDirectedSphereEmitter(1.2, new BABYLON.Vector3(1, 1, 1), new BABYLON.Vector3(2, 8, 2));

该createDirectedSphereEmitter方法按以下顺序采用三个参数:

  • radius:数字 - 球体发射器的半径
  • direction1:Vector3 - 第一个方向
  • direction2:Vector3 - 第二个方向

我们也可以直接在创建的对象上面修改:

sphereEmitter.radius = 3.4;
sphereEmitter.direction1 = new BABYLON.Vector3(-5, 2, 1); 
sphereEmitter.direction2 = new BABYLON.Vector3(5, 2, -1);

第一个参数是半径,第二个是direction1,第三个是direction2。(方向将在direction1和direction2之间随机生成)

半球发射器

你可以创建设置半径的半球发射器,例如1.2:

var hemisphericEmitter = particleSystem.createHemisphericEmitter(1.2);

半球和球体一样,粒子也是沿着球心到生成位置的方向移动。

你还可以设置hemisphericEmitter.radiusRange属性是沿表面还是在球内。如果值为0,表示随机在球的表面,如果值为1,则在球内随机产生。

圆柱发射器

你可以通过设置半径,高度,生成位置,以及是否随机方向来创建圆柱发射器:

var cylinderEmitter = particleSystem.createCylinderEmitter(1,1,0,0);

返回的cylinderEmitter对象也可以进行修改相关属性。

设置cylinderEmitter .radiusRange属性是沿表面还是在圆柱内。如果值为0,表示随机在圆柱的表面,如果值为1,则在圆柱内随机产生。设置cylinderEmitter.directionRandomizer可以改变粒子方向随机化的程度。0为不随机,1为随机。

我们还可以通过createDirectedCylinderEmitter创建设置方向的圆柱发射器:

  • radius:Number,- 圆柱的半径
  • height:Number,- 圆柱的高度
  • radiusRange:Number,- 圆柱的粒子产生位置 值为 0 或1
  • direction1:Vector3, - 第一个方向
  • direction2:Vector3, - 第二个方向

返回的cylinderEmitter对象可用于更改这些属性的值。

cylinderEmitter.radius = 3.4;
cylinderEmitter.direction1 = new BABYLON.Vector3(-5, 2, 1); 
cylinderEmitter.direction2 = new BABYLON.Vector3(5, 2, -1);

第一个参数是半径,第二个是direction1,第三个是direction2。(方向将在direction1和direction2之间随机生成)

锥形发射器

比如,创建一个简单的锥形发射器:

var coneEmitter = particleSystem.createConeEmitter(2, Math.PI / 3);

该createConeEmitter方法按以下顺序采用两个参数

  • radius:Number; - 半径
  • angle:以弧度为单位测量的数字,锥体的角度。

创建的圆锥的顶点在底部,锥的中心线在Y轴。
设置coneEmitter.radiusRange属性是沿表面还是在圆锥内。如果值为0,表示随机在圆锥的表面,如果值为1,则在圆锥内随机产生。
这个同样适用于coneEmitter.heightRange:你可以定义粒子产生位置的高度,0表示仅在顶部表面,1则表示整个高度。

返回的coneEmitter对象可用于更改这些属性的值。

coneEmitter.radius = 3.4;
coneEmitter.angle = Math.PI / 2;

设置coneEmitter.emitFromSpawnPointOnly = true可以强制粒子在圆锥的顶点产生。

噪音纹理

从Babylon.js v3.3版本开始,你可以使用噪音纹理来改变粒子的方向:

var noiseTexture = new BABYLON.NoiseProceduralTexture("perlin", 256, scene);
noiseTexture.animationSpeedFactor = 5;
noiseTexture.persistence = 2;
noiseTexture.brightness = 0.5;
noiseTexture.octaves = 2;

particleSystem.noiseTexture = noiseTexture;
particleSystem.noiseStrength = new BABYLON.Vector3(100, 100, 100);

除了设置noiseTexture,你还可以通过particleSystem.noiseStrength控制每个轴上面的强度。

GPU粒子

从Babylon.js v3.2版本开始,你可以使用WebGL2的特性(transform feedback buffer 变换反馈缓冲区)来大幅提升粒子的性能。常规的粒子使用CPU进行动画,而用于渲染新WebGL2 API的GPU允许Babylon.js将GPU用于动画和渲染。
不幸的是,此功能仅在支持WebGL2的浏览器上面可用。你可以使用BABYLON.GPUParticleSystem.IsSupported来检测当前是否可用GPU粒子。如果支持它们,GPU粒子几乎可以像常规粒子一样使用:

var particleSystem = new BABYLON.GPUParticleSystem("particles", { capacity:1000000 }, scene);

以上设置了创建了一个1000000个粒子的粒子系统。此外,如果要限制GPU使用量,可以使用particleSystem.activeParticleCount来定义活动粒子量。
注意:GPU粒子不支持粒子发射器。

随机粒子

遗憾的是,在GPU上面没有好方法获取随机数。为了解决这个问题,Babylon.js将创建一个填充了数千个随机值的纹理。粒子更新着色器时,将使用这些值来创建动画。默认情况下,使用最大支持的纹理大小(16k)。如果你希望减小纹理的大小,使用下面方法:

var particleSystem = new BABYLON.GPUParticleSystem("particles", { capacity:1000000, randomTextureSize: 4096 }, scene);

回退版本

由于GPUParticleSystem和ParticleSystem几乎共享所有API,因此切换起来比较方便,我们可以在不支持GPU粒子的浏览器切换成原始的粒子系统。请记住,CPU无法为GPU提供尽可能多的粒子动画。因此,在不使用GPUParticleSystem时,你可能需要降低粒子的总量。

停止使用GPU粒子系统

停止使用一个粒子系统需要使用system.stop(),这样会让当前GPU粒子系统产生新的粒子。但是即使是不可见,粒子仍然被渲染。
要销毁一个GPU粒子系统,必须调用dispose()来销毁它。

GPU粒子系统不支持的功能

  • ManualEmitCount
  • Custom effects
  • Animation sheets
  • disposeOnStop
  • Dual values per gradient (only one value is supported)
  • Emit rate gradients are not supported
  • Start size gradients are not supported

示例

发布了402 篇原创文章 · 获赞 544 · 访问量 212万+

猜你喜欢

转载自blog.csdn.net/qq_30100043/article/details/88386353
今日推荐