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

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

我们可以通过控制一堆 Sprite 运动来实现各种粒子效果,但很多运动想自己计算还是挺麻烦的,比如爆炸的粒子运动。
所以我们还是用粒子库来做。
先看下 three.quarks 实现的效果:




自己来计算每一帧里这些粒子运动到了什么位置,是件很麻烦的事情。
所以我们直接来学 three.quarks 吧
创建项目:
npx create-vite three-quarks-test

进入项目,安装依赖:
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;
这里代码比较多,从上到下看下:
首先创建粒子系统的批量渲染器:

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


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

使用刚才加载的纹理。
动画时长 20s,循环执行。

每个粒子的生命周期在 0 到 10s 之间随机,也就是有的粒子存活 10s,有的 3s。
速度在 0 到 500 之间随机。
大小在 0 到 100 之间随机
颜色要指定 rgba 的四元数,在红、绿之间随机。
emissionOverTime 是每次发射多少个新的粒子,这里指定固定的 100 个。
shape 是点发射器 PointEmitter
然后我们在 main.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


可以看到,从一个点向四周发射心的粒子动画就完成了。
如果自己写这个粒子效果也可以,就是每一帧计算 Sprite 的位置即可。
但用了 three.quarks 只要设置下参数就行。
我们改一下颜色混合模式,默认材质之间互不影响,我们改为颜色叠加:

blending: THREE.AdditiveBlending,

可以看到,红色、绿色会叠加为黄色,这样中心点就更明显了。
案例代码上传了小册仓库
总结
这节我们入门了粒子动画库 three.quarks
粒子就是通过一堆小的物体的运动来实现雾、火、水、爆炸等效果。
如果自己实现粒子效果,要每帧计算一堆粒子的位置,而通过 three.quarks 库,只要设置参数就行。
我们创建了渲染器 BatchedParticleRenderer,然后创建粒子系统 ParticleSystem
指定动画时长,随机的颜色、速度、大小,指定发射器形状等,就可以实现爱心发射器的粒子效果。
当然,three.quarks 可以实现的粒子效果还有很多,下节我们继续学习。