WEBKT

Babylon.js 粒子系统定制:从入门到精通,打造你的专属特效

4 0 0 0

1. 粒子系统概述

1.1 粒子系统的基本构成

1.2 Babylon.js 中的粒子系统核心类

2. 创建一个简单的粒子系统

3. 定制粒子发射器

3.1 使用不同的发射器类型

3.2 自定义发射器的方向和范围

3.3 动态调整发射器属性

4. 自定义粒子属性

4.1 颜色

4.2 大小

4.3 生命周期

4.4 速度

4.5 旋转

4.6 重力

4.7 纹理

5. 高级技巧

5.1 使用自定义更新函数

5.2 使用碰撞检测

5.3 使用外部模块扩展粒子系统

6. 性能优化

7. 实际案例:制作火焰效果

8. 总结

9. 拓展阅读

嘿,老铁们!我是你们的老朋友,一个热爱折腾各种前端技术的程序猿。今天咱们聊聊在 Babylon.js 中怎么玩转粒子系统,让你的 3D 场景更酷炫,更具视觉冲击力!

1. 粒子系统概述

在 3D 图形学中,粒子系统是一种模拟大量微小物体(也就是粒子)的技术,常用于创建各种视觉效果,比如烟雾、火焰、爆炸、水流、雪花等等。Babylon.js 提供了强大的粒子系统,可以让你轻松实现这些效果。

1.1 粒子系统的基本构成

  • 粒子(Particle): 粒子是构成粒子系统的基本单位,每个粒子都有自己的位置、速度、颜色、大小、生命周期等属性。
  • 发射器(Emitter): 发射器负责创建和发射粒子,它定义了粒子的初始位置、方向、速度等。
  • 材质(Material): 材质定义了粒子的外观,比如颜色、纹理、透明度等。
  • 更新器(Updater): 更新器负责更新粒子的属性,比如位置、速度、颜色、大小等,使粒子产生运动和变化。
  • 粒子系统(Particle System): 粒子系统是整个效果的管理者,它包含发射器、材质、更新器等,并负责控制粒子的生命周期和渲染。

1.2 Babylon.js 中的粒子系统核心类

  • ParticleSystem: 粒子系统的核心类,用于管理和渲染粒子。
  • Particle: 代表单个粒子的类,通常我们不会直接操作这个类,而是通过ParticleSystem来控制粒子。
  • IParticleEmitter: 粒子发射器的接口,定义了发射器的基本方法。
  • MeshParticleEmitter: 基于网格的粒子发射器,可以从网格的顶点、表面等发射粒子。
  • SphereParticleEmitter: 基于球体的粒子发射器,可以从球体的内部或表面发射粒子。
  • BoxParticleEmitter: 基于盒子的粒子发射器,可以从盒子的内部或表面发射粒子。
  • PointParticleEmitter: 基于点的粒子发射器,可以从一个点发射粒子。
  • Texture: 用于定义粒子的材质纹理,可以使粒子具有更丰富的视觉效果。

2. 创建一个简单的粒子系统

让我们从一个简单的例子开始,创建一个从中心点向外发射的粒子系统。

// 创建一个 Babylon.js 场景
const canvas = document.getElementById('renderCanvas');
const engine = new BABYLON.Engine(canvas, true);
const createScene = function () {
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.ArcRotateCamera(
'Camera',
Math.PI / 2,
Math.PI / 2,
2,
new BABYLON.Vector3(0, 0, 0),
scene
);
camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight(
'hemiLight',
new BABYLON.Vector3(0, 1, 0),
scene
);
// 创建一个粒子系统
const particleSystem = new BABYLON.ParticleSystem('particles', 2000, scene);
// 设置粒子纹理
particleSystem.particleTexture = new BABYLON.Texture(
'https://www.babylonjs-playground.com/textures/flare.png', // 替换为你的纹理地址
scene
);
// 设置发射器
particleSystem.emitter = new BABYLON.Vector3(0, 0, 0); // 从中心点发射
particleSystem.minEmitBox = new BABYLON.Vector3(-1, -1, -1); // 发射范围
particleSystem.maxEmitBox = new BABYLON.Vector3(1, 1, 1);
// 设置粒子属性
particleSystem.color1 = new BABYLON.Color4(1, 0, 0, 1); // 红色
particleSystem.color2 = new BABYLON.Color4(0, 1, 0, 1); // 绿色
particleSystem.colorDead = new BABYLON.Color4(0, 0, 0, 0); // 死亡颜色,透明
particleSystem.minSize = 0.1; // 最小尺寸
particleSystem.maxSize = 0.5; // 最大尺寸
particleSystem.minLifeTime = 0.3; // 最小生命周期
particleSystem.maxLifeTime = 1.5; // 最大生命周期
particleSystem.emitRate = 150; // 每秒发射的粒子数量
particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE; // 混合模式
particleSystem.gravity = new BABYLON.Vector3(0, -0.1, 0); // 重力
particleSystem.direction1 = new BABYLON.Vector3(-1, 1, -1); // 发射方向
particleSystem.direction2 = new BABYLON.Vector3(1, 1, 1);
particleSystem.minEmitPower = 1; // 最小发射强度
particleSystem.maxEmitPower = 3; // 最大发射强度
// 开始发射
particleSystem.start();
return scene;
};
const scene = createScene();
engine.runRenderLoop(function () {
scene.render();
});
// 浏览器窗口大小改变时,调整引擎大小
window.addEventListener('resize', function () {
engine.resize();
});

在这个例子中:

  1. 我们创建了一个ParticleSystem实例,并指定了最大粒子数量为 2000。
  2. 我们设置了粒子纹理,这里使用了一个简单的 flare 纹理,你也可以替换成自己的纹理。
  3. 我们设置了发射器的位置为 (0, 0, 0),也就是场景的中心点,并且定义了一个发射范围。
  4. 我们设置了粒子的颜色、大小、生命周期、发射速率等属性,你可以根据自己的需求进行调整。
  5. 我们设置了粒子的混合模式、重力、发射方向和发射强度。
  6. 最后,我们调用particleSystem.start()方法启动粒子系统。

运行这段代码,你应该能看到从中心点向外发射的彩色粒子效果。

3. 定制粒子发射器

Babylon.js 提供了多种粒子发射器,可以满足不同的需求。接下来,我们来详细了解一下如何定制粒子发射器。

3.1 使用不同的发射器类型

  • MeshParticleEmitter: 从网格的顶点、表面等发射粒子,可以创建更复杂的发射效果。例如,你可以让粒子从一个立方体的表面喷射出来。

    // 创建一个立方体网格
    const box = BABYLON.MeshBuilder.CreateBox('box', { size: 1 }, scene);
    // 创建粒子系统
    const particleSystem = new BABYLON.ParticleSystem('particles', 2000, scene);
    particleSystem.particleTexture = new BABYLON.Texture('https://www.babylonjs-playground.com/textures/flare.png', scene);
    particleSystem.emitter = box; // 将立方体设置为发射器
    particleSystem.minEmitBox = new BABYLON.Vector3(0, 0, 0); // 发射范围
    particleSystem.maxEmitBox = new BABYLON.Vector3(1, 1, 1);
    particleSystem.emitRate = 200; // 调整发射速率
    particleSystem.start();
  • SphereParticleEmitter: 从球体的内部或表面发射粒子,可以创建球形或环状的发射效果。例如,你可以模拟星球爆炸。

    // 创建一个球体网格
    const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', { diameter: 2 }, scene);
    // 创建粒子系统
    const particleSystem = new BABYLON.ParticleSystem('particles', 2000, scene);
    particleSystem.particleTexture = new BABYLON.Texture('https://www.babylonjs-playground.com/textures/flare.png', scene);
    particleSystem.emitter = sphere; // 将球体设置为发射器
    particleSystem.minEmitBox = new BABYLON.Vector3(0, 0, 0); // 发射范围
    particleSystem.maxEmitBox = new BABYLON.Vector3(2, 2, 2);
    particleSystem.emitRate = 100; // 调整发射速率
    particleSystem.start();
  • BoxParticleEmitter: 从盒子的内部或表面发射粒子,可以创建立方体或矩形的发射效果。例如,你可以模拟喷泉。

    // 创建一个盒子网格
    const box = BABYLON.MeshBuilder.CreateBox('box', { size: 2 }, scene);
    // 创建粒子系统
    const particleSystem = new BABYLON.ParticleSystem('particles', 2000, scene);
    particleSystem.particleTexture = new BABYLON.Texture('https://www.babylonjs-playground.com/textures/flare.png', scene);
    particleSystem.emitter = box; // 将盒子设置为发射器
    particleSystem.minEmitBox = new BABYLON.Vector3(-1, 0, -1); // 发射范围
    particleSystem.maxEmitBox = new BABYLON.Vector3(1, 0, 1);
    particleSystem.emitRate = 150; // 调整发射速率
    particleSystem.start();
  • PointParticleEmitter: 从一个点发射粒子,可以创建点状的发射效果。例如,你可以模拟流星。

    // 创建粒子系统
    const particleSystem = new BABYLON.ParticleSystem('particles', 2000, scene);
    particleSystem.particleTexture = new BABYLON.Texture('https://www.babylonjs-playground.com/textures/flare.png', scene);
    particleSystem.emitter = new BABYLON.Vector3(0, 0, 0); // 设置发射器位置
    particleSystem.minEmitBox = new BABYLON.Vector3(0, 0, 0); // 发射范围
    particleSystem.maxEmitBox = new BABYLON.Vector3(0, 0, 0);
    particleSystem.emitRate = 50; // 调整发射速率
    particleSystem.direction1 = new BABYLON.Vector3(0, 1, 0); // 发射方向
    particleSystem.direction2 = new BABYLON.Vector3(0, 1, 0);
    particleSystem.start();

3.2 自定义发射器的方向和范围

除了使用不同的发射器类型,你还可以通过设置direction1direction2minEmitBoxmaxEmitBox等属性来控制粒子的发射方向和范围。

  • direction1direction2: 这两个属性定义了粒子的发射方向。direction1direction2 之间的范围将决定粒子的发射角度。
  • minEmitBoxmaxEmitBox: 这两个属性定义了粒子发射的范围。如果发射器是一个点,那么minEmitBoxmaxEmitBox就定义了一个立方体,粒子从这个立方体内部随机位置发射。如果发射器是一个网格,那么minEmitBoxmaxEmitBox定义了一个向量偏移,粒子从网格的表面或体积中发射,偏移量是相对于发射器中心点的。

举个例子,如果你想让粒子向上喷射,可以这样设置:

particleSystem.direction1 = new BABYLON.Vector3(0, 1, 0); // 向上
particleSystem.direction2 = new BABYLON.Vector3(0, 1, 0); // 向上

如果想让粒子向四周发散,可以这样设置:

particleSystem.direction1 = new BABYLON.Vector3(-1, 1, -1); // 随机方向
particleSystem.direction2 = new BABYLON.Vector3(1, 1, 1); // 随机方向

3.3 动态调整发射器属性

你可以通过代码动态地调整发射器的属性,从而创建更具动态性和交互性的效果。例如,你可以根据用户输入或者游戏事件来改变粒子的发射方向、速度、发射速率等。

// 假设你有一个控制发射方向的变量
let emissionDirection = new BABYLON.Vector3(0, 1, 0);
// 动态更新发射方向
scene.registerBeforeRender(() => {
particleSystem.direction1 = emissionDirection.scale(-1);
particleSystem.direction2 = emissionDirection;
});
// 示例:改变发射方向
function changeEmissionDirection(x, y, z) {
emissionDirection = new BABYLON.Vector3(x, y, z);
}

4. 自定义粒子属性

除了发射器,你还可以自定义粒子的各种属性,从而创建更丰富和个性化的视觉效果。

4.1 颜色

  • color1color2: 定义了粒子的初始颜色。
  • colorDead: 定义了粒子死亡时的颜色。

你可以使用Color4对象来设置颜色,Color4对象包含红、绿、蓝和透明度四个分量。

particleSystem.color1 = new BABYLON.Color4(1, 0, 0, 1); // 红色,完全不透明
particleSystem.color2 = new BABYLON.Color4(0, 1, 0, 1); // 绿色,完全不透明
particleSystem.colorDead = new BABYLON.Color4(0, 0, 0, 0); // 黑色,完全透明,粒子死亡时消失

你还可以通过设置不同的color1color2,使粒子在生命周期内颜色发生渐变。

4.2 大小

  • minSize: 定义了粒子的最小尺寸。
  • maxSize: 定义了粒子的最大尺寸。
particleSystem.minSize = 0.1; // 最小尺寸
particleSystem.maxSize = 0.5; // 最大尺寸

你还可以通过设置updateSize来控制粒子在生命周期内的尺寸变化。

particleSystem.updateSize = function(particle) {
particle.size = particle.startSize * (1 - particle.life / particle.lifeTime);
};

4.3 生命周期

  • minLifeTime: 定义了粒子的最短生命周期。
  • maxLifeTime: 定义了粒子的最长生命周期。
particleSystem.minLifeTime = 0.5; // 最小生命周期
particleSystem.maxLifeTime = 2; // 最大生命周期

4.4 速度

  • minEmitPower: 定义了粒子的最小发射强度,影响粒子的初始速度。
  • maxEmitPower: 定义了粒子的最大发射强度。
particleSystem.minEmitPower = 1; // 最小发射强度
particleSystem.maxEmitPower = 3; // 最大发射强度

4.5 旋转

你可以让粒子在运动过程中进行旋转。

  • minAngularSpeed: 定义了粒子的最小角速度。
  • maxAngularSpeed: 定义了粒子的最大角速度。
particleSystem.minAngularSpeed = 0; // 最小角速度
particleSystem.maxAngularSpeed = Math.PI / 2; // 最大角速度
particleSystem.updateRotation = function(particle) {
particle.angle += particle.angularSpeed * engine.getDeltaTime() / 1000;
particle.rotation.z = particle.angle;
};

4.6 重力

  • gravity: 定义了粒子受到的重力。
particleSystem.gravity = new BABYLON.Vector3(0, -0.1, 0); // 重力方向向下

4.7 纹理

  • particleTexture: 定义了粒子的纹理。

你可以使用各种纹理来改变粒子的外观。

particleSystem.particleTexture = new BABYLON.Texture('https://www.babylonjs-playground.com/textures/flare.png', scene);

你还可以使用精灵图来创建动画效果。 Babylon.js 提供了spriteCellChangeLimitspriteCellChangeSpeed等属性来控制精灵动画。

5. 高级技巧

5.1 使用自定义更新函数

你可以通过自定义更新函数来控制粒子的属性变化,实现更复杂的动画效果。

particleSystem.updateParticle = function(particle) {
// 示例:改变粒子的透明度
particle.color.a = 1 - particle.life / particle.lifeTime;
// 示例:改变粒子的缩放
particle.scale = 1 - particle.life / particle.lifeTime;
};

5.2 使用碰撞检测

你可以使用碰撞检测来使粒子与场景中的其他物体交互。 Babylon.js 提供了collisionModule模块来实现碰撞检测。

// 启用碰撞检测
particleSystem.collisionModule = new BABYLON.ParticleSystem.CollisionModule(scene);
particleSystem.collisionModule.enable();
// 设置碰撞的物体
particleSystem.collisionModule.collidable = true;
particleSystem.collisionModule.plane = new BABYLON.Plane(0, 1, 0, 0); // 示例:与地面碰撞

5.3 使用外部模块扩展粒子系统

Babylon.js 允许你使用外部模块来扩展粒子系统的功能。例如,你可以使用PostProcess来实现粒子系统的后期处理效果,或者使用自定义的Updater来实现更复杂的粒子行为。

6. 性能优化

在使用粒子系统时,性能是一个需要考虑的重要因素。以下是一些性能优化的技巧:

  • 限制粒子数量: 减少粒子数量可以显著提高性能。尽量使用最少的粒子数量来实现你想要的效果。
  • 使用合适的纹理: 使用大小合适的纹理,避免使用过大的纹理,这会占用大量的显存。
  • 减少更新频率: 如果粒子效果不需要非常高的帧率,可以适当降低更新频率。
  • 合并粒子系统: 如果你的场景中有很多粒子系统,可以尝试将它们合并成一个粒子系统,减少 Draw Call。
  • 使用 LOD: 对于距离相机较远的粒子系统,可以使用 LOD(Level of Detail)技术,降低粒子的复杂度和数量。
  • 使用 GPU 粒子: Babylon.js 支持 GPU 粒子,可以利用 GPU 的并行计算能力来加速粒子系统的渲染。

7. 实际案例:制作火焰效果

让我们结合前面所学的知识,尝试制作一个火焰效果。

const createFire = function () {
// 创建火焰粒子系统
const fireSystem = new BABYLON.ParticleSystem('fire', 1000, scene);
// 设置纹理
fireSystem.particleTexture = new BABYLON.Texture(
'https://www.babylonjs-playground.com/textures/flare.png', // 替换为你的火焰纹理
scene
);
// 设置发射器
fireSystem.emitter = new BABYLON.Vector3(0, 0, 0); // 火焰从中心点发射
fireSystem.minEmitBox = new BABYLON.Vector3(-0.2, 0, -0.2); // 发射范围
fireSystem.maxEmitBox = new BABYLON.Vector3(0.2, 0, 0.2);
// 设置粒子属性
fireSystem.color1 = new BABYLON.Color4(1, 0.5, 0, 1); // 橙色
fireSystem.color2 = new BABYLON.Color4(1, 0.2, 0, 1); // 红色
fireSystem.colorDead = new BABYLON.Color4(0, 0, 0, 0); // 死亡颜色
fireSystem.minSize = 0.1; // 最小尺寸
fireSystem.maxSize = 0.5; // 最大尺寸
fireSystem.minLifeTime = 0.5; // 最小生命周期
fireSystem.maxLifeTime = 1.0; // 最大生命周期
fireSystem.emitRate = 100; // 发射速率
fireSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE; // 混合模式
fireSystem.gravity = new BABYLON.Vector3(0, 0.1, 0); // 重力向上
fireSystem.direction1 = new BABYLON.Vector3(-0.2, 1, -0.2); // 发射方向
fireSystem.direction2 = new BABYLON.Vector3(0.2, 1, 0.2);
fireSystem.minEmitPower = 1; // 最小发射强度
fireSystem.maxEmitPower = 3; // 最大发射强度
fireSystem.updateParticle = function (particle) {
// 调整透明度
particle.color.a = 1 - particle.life / particle.lifeTime;
// 调整缩放
particle.scale = 1 - particle.life / particle.lifeTime;
};
// 开始发射
fireSystem.start();
return fireSystem;
};
// 创建火焰
const fire = createFire();

在这个例子中:

  1. 我们使用了一个橙色和红色的flare纹理来模拟火焰的颜色。
  2. 我们设置了粒子向上发射,并模拟了重力向上漂浮的效果。
  3. 我们使用updateParticle函数来控制粒子在生命周期内的透明度和缩放变化,使火焰效果更真实。

8. 总结

通过本教程,相信你已经对 Babylon.js 的粒子系统有了更深入的了解。你可以根据自己的需求,自定义粒子系统的各种属性,创造出各种令人惊叹的视觉效果。 记住,多实践,多尝试,才能熟练掌握这些技术!

9. 拓展阅读

祝你编程愉快,创作出属于自己的精彩 3D 世界! 咱们下次再见!

技术老司机 Babylon.js粒子系统3D前端开发

评论点评

打赏赞助
sponsor

感谢您的支持让我们更好的前行

分享

QRcode

https://www.webkt.com/article/8289