Skip to content

155. 粒子效果库 three.quarks

Published:

这节我们来学习一个粒子效果库 three.quarks

image.png

粒子效果是由无数个单个粒子组合形成的水、火、雾、气等效果:

image.png

我们可以通过控制一堆 Sprite 运动来实现各种粒子效果,但很多运动想自己计算还是挺麻烦的,比如爆炸的粒子运动。

所以我们还是用粒子库来做。

先看下 three.quarks 实现的效果

2025-06-01 10.13.29.gif

2025-06-01 10.14.19.gif

2025-06-01 10.15.13.gif

2025-06-01 10.16.04.gif

自己来计算每一帧里这些粒子运动到了什么位置,是件很麻烦的事情。

所以我们直接来学 three.quarks 吧

创建项目:

npx create-vite three-quarks-test

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

写下 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('./heart.png');

const particles = new ParticleSystem({
    duration: 20,
    looping: true,
    startLife: new IntervalValue(0, 10),
    startSpeed: new IntervalValue(0, 500),
    startSize: new IntervalValue(0, 100),
    startColor: new RandomColor(
        new THREE.Vector4(1, 0, 0, 1),
        new THREE.Vector4(0, 1, 0, 1)
    ),
    emissionOverTime: new ConstantValue(100),
    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;

这里代码比较多,从上到下看下:

首先创建粒子系统的批量渲染器:

image.png

然后加载下粒子的纹理图片:

image.png

heart.png

然后初始化粒子系统 ParticleSystem,首先指定材质:

image.png

使用刚才加载的纹理。

动画时长 20s,循环执行。

image.png

每个粒子的生命周期在 0 到 10s 之间随机,也就是有的粒子存活 10s,有的 3s。

速度在 0 到 500 之间随机。

大小在 0 到 100 之间随机

颜色要指定 rgba 的四元数,在红、绿之间随机。

emissionOverTime 是每次发射多少个新的粒子,这里指定固定的 100 个。

shape 是点发射器 PointEmitter

然后我们在 main.js 的渲染循环里更新下:

image.png

image.png

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 11.51.29.gif

可以看到,从一个点向四周发射心的粒子动画就完成了。

如果自己写这个粒子效果也可以,就是每一帧计算 Sprite 的位置即可。

但用了 three.quarks 只要设置下参数就行。

我们改一下颜色混合模式,默认材质之间互不影响,我们改为颜色叠加:

image.png

blending: THREE.AdditiveBlending,

2025-06-01 11.55.32.gif

可以看到,红色、绿色会叠加为黄色,这样中心点就更明显了。

案例代码上传了小册仓库

总结

这节我们入门了粒子动画库 three.quarks

粒子就是通过一堆小的物体的运动来实现雾、火、水、爆炸等效果。

如果自己实现粒子效果,要每帧计算一堆粒子的位置,而通过 three.quarks 库,只要设置参数就行。

我们创建了渲染器 BatchedParticleRenderer,然后创建粒子系统 ParticleSystem

指定动画时长,随机的颜色、速度、大小,指定发射器形状等,就可以实现爱心发射器的粒子效果。

当然,three.quarks 可以实现的粒子效果还有很多,下节我们继续学习。

评论