Skip to content

157. 各种形状的粒子发射器

Published:

前面我们用过点状粒子发射器 PointEmitter:

2025-06-01 11.55.32.gif

锥形粒子发射器 ConeEmiiter

2025-06-01 13.27.13.gif

那还有没有其他形状的发射器呢?

有的,还有球形、半球形、圆形等。

不同的需求,需要用不同形状的发射器。

这节我们把各种形状的发射器用一遍。

npx create-vite all-shape-three-quarks

image.png

进入项目,安装依赖:

npm install
npm install --save three
npm install --save-dev @types/three

改下 src/main.js

import './style.css';
import * as THREE from 'three';
import {
    OrbitControls
} from 'three/addons/controls/OrbitControls.js';
import mesh from './mesh.js';

const scene = new THREE.Scene();

scene.add(mesh);

const directionLight = new THREE.DirectionalLight(0xffffff);
directionLight.position.set(500, 600, 800);
scene.add(directionLight);

const ambientLight = new THREE.AmbientLight();
scene.add(ambientLight);

const helper = new THREE.AxesHelper(1000);
scene.add(helper);

const width = window.innerWidth;
const height = window.innerHeight;

const camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 10000);
camera.position.set(500, 600, 800);
camera.lookAt(0, 0, 0);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height)

function render() {
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}

render();

document.body.append(renderer.domElement);

const controls = new OrbitControls(camera, renderer.domElement);

创建 Scene、Light、Camera、Renderer。

改下 style.css

body {
  margin: 0;
}

安装下粒子效果库:

npm install --save three.quarks

PointEmitter 点状粒子发射器

初始化下 three.quarks

写下 mesh.js

import * as THREE from "three";
import { BatchedParticleRenderer, ConstantValue, IntervalValue, ParticleSystem,PointEmitter,RandomColor, RenderMode } from "three.quarks";

const group = new THREE.Group();

const batchRenderer = new BatchedParticleRenderer();
group.add(batchRenderer);

const loader = new THREE.TextureLoader();
const texture = loader.load('./point.png');

const particles = new ParticleSystem({
    duration: 20,
    looping: true,
    startLife: new IntervalValue(0, 10),
    startSpeed: new IntervalValue(0, 500),
    startSize: new IntervalValue(0, 10),
    startColor: new RandomColor(
        new THREE.Vector4(1, 0.5, 0.5, 1),
        new THREE.Vector4(0.5, 0.5, 1, 1)
    ),
    emissionOverTime: new ConstantValue(1000),
    shape: new PointEmitter(),
    material: new THREE.MeshBasicMaterial({
        map: texture,
        transparent: true,
        side: THREE.DoubleSide
    })
});

group.add(particles.emitter);

batchRenderer.addSystem(particles);

export {
    batchRenderer
}

export default group;

我们把粒子大小设置为 0 到 10 随机

然后每次发射的数量设置为 1000

point.png 是这张图片:

image.png

point.png

(上面有张图片,背景透明的白色圆点)

在 main.js 里初始化一下:

image.png

import { batchRenderer } from './mesh.js';
const clock = new THREE.Clock();
function render() {
  const delta = clock.getDelta();

  renderer.render(scene, camera);
  requestAnimationFrame(render);

  if(batchRenderer) {
    batchRenderer.update(delta);
  }
}

跑一下:

npm run dev

image.png

看下效果:

2025-06-01 15.56.23.gif

可以看到,是点状发射的粒子。

ConeEmitter 锥形粒子发射器

改成锥形粒子试试,我们上节用过:

image.png

shape: new ConeEmitter({
    radius: 0,
    thickness: 0,
    arc: Math.PI * 2,
    angle: Math.PI / 15
}),

2025-06-01 16.05.08.gif

angle 可以调节这个锥形的大小

angle 调大一点:

image.png

2025-06-01 16.06.17.gif

可以看到,锥形的角度变大了。

radius 则是从半径为多少的地方开始,比如改成 100

image.png

2025-06-01 16.07.42.gif

明显就少了一部分。

thickness 是疏密程度,改大一点:

image.png

2025-06-01 16.09.50.gif

稀疏了很多。

SphereEmitter 球状粒子发射器

SphereEimtter 是球形发射器。

image.png

设置下半径,厚度,角度

这里我们把每次发射的粒子调大为 10000,速度调整为 0 到 100

看下效果:

startSpeed: new IntervalValue(0, 100),
emissionOverTime: new ConstantValue(10000),
shape: new SphereEmitter({
    radius: 500,
    thickness: 0,
    arc: Math.PI * 2
}),

2025-06-01 16.19.21.gif

可以明显看到是从一个球形开始向四周发射的。

HemisphereEmitter 半球粒子发射器

HemisphereEmitter 顾名思义,这个是半球状。

image.png

shape: new HemisphereEmitter({
    radius: 500,
    thickness: 0,
    arc: Math.PI * 2
}),

看下效果:

2025-06-01 16.22.25.gif

CircleEmitter

CircleEimtter 是圆形,是 2D 平面的粒子效果

image.png

shape: new CircleEmitter({
    radius: 200,
    thickness: 0,
    arc: Math.PI  * 2
}),

2025-06-01 16.29.06.gif

DonutEmitter

DonutEmitter 是圆环粒子发射器,从圆环开始往外发射粒子。

image.png

shape: new DonutEmitter({
    radius: 500,
    thickness: 0,
    arc: Math.PI  * 2,
    donutRadius: 50
}),

这里的 donutRadius 就是圆环半径。

看下效果:

2025-06-01 16.33.08.gif

RectangleEmitter

RectangleEmitter 是矩形的粒子发射器

image.png

shape: new RectangleEmitter({
    width: 300,
    height: 400,
}),

看下效果:

2025-06-01 16.38.09.gif

GridEmitter

这个比较有意思,是网格状的。

image.png

image.png

shape: new GridEmitter({
    width: 300,
    height: 400,
    row: 5,
    column: 6
}),

指定 width、height 和分的行列数。

把每次发射的粒子数量调小一点。

看下效果:

2025-06-01 16.43.51.gif

案例代码上传了小册仓库

总结

这节我们过了一遍各种形状的粒子发射器。

有点状、锥形、球形、半球形、圆形、圆环形、矩形、Grid。

在不同的场景下,可以使用不同形状的粒子发射器。

评论