使用最新版three.js的粒子系统实现火焰效果
时间: 2023-06-29 12:03:37 浏览: 360
基于three.js的火焰demo
5星 · 资源好评率100%
要实现火焰效果,我们可以使用Three.js的粒子系统,并结合一些纹理图像来模拟火焰的外观。
首先,我们需要创建一个粒子系统:
```javascript
const particleCount = 1000;
const particles = new THREE.Geometry();
const pMaterial = new THREE.PointsMaterial({
color: 0xff0000,
size: 0.5,
map: fireTexture, // 这里是我们用来模拟火焰外观的纹理图像
blending: THREE.AdditiveBlending,
transparent: true
});
for (let i = 0; i < particleCount; i++) {
const particle = new THREE.Vector3(
Math.random() * 2 - 1,
Math.random() * 2 - 1,
Math.random() * 2 - 1
);
particles.vertices.push(particle);
}
const particleSystem = new THREE.Points(particles, pMaterial);
```
我们使用了一个THREE.Geometry对象来存储粒子的位置信息,并创建了一个THREE.PointsMaterial对象来定义粒子的颜色、大小、纹理等属性。在循环中,我们随机生成了1000个三维向量作为粒子的初始位置,并将它们添加到Geometry对象中。
接下来,我们需要将粒子系统添加到场景中并更新粒子的位置:
```javascript
scene.add(particleSystem);
function animate() {
requestAnimationFrame(animate);
for (let i = 0; i < particleCount; i++) {
const particle = particles.vertices[i];
particle.y -= 0.01; // 粒子下降的速度
particle.x += Math.random() * 0.01 - 0.005; // 随机横向偏移
particle.z += Math.random() * 0.01 - 0.005; // 随机纵向偏移
if (particle.y < -1) { // 如果粒子掉落到底部,重新回到顶部
particle.y = 1;
}
}
particles.verticesNeedUpdate = true; // 更新粒子位置信息
renderer.render(scene, camera);
}
```
在动画循环中,我们遍历所有粒子,让它们向下移动一定的速度,并且在x和z轴上随机偏移一定的距离。如果粒子掉落到场景底部,我们将它重新回到场景顶部。最后,我们需要设置`particles.verticesNeedUpdate`为true,以便让Three.js知道我们更新了粒子的位置信息。
最后别忘了要在HTML中引入相关的纹理图像和Three.js库:
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<img id="fireTexture" src="fire.png" style="display: none;">
```
完整的代码如下:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Fire Effect with Three.js</title>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<img id="fireTexture" src="fire.png" style="display: none;">
<script>
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const particleCount = 1000;
const particles = new THREE.Geometry();
const fireTexture = new THREE.TextureLoader().load('fire.png');
const pMaterial = new THREE.PointsMaterial({
color: 0xff0000,
size: 0.5,
map: fireTexture,
blending: THREE.AdditiveBlending,
transparent: true
});
for (let i = 0; i < particleCount; i++) {
const particle = new THREE.Vector3(
Math.random() * 2 - 1,
Math.random() * 2 - 1,
Math.random() * 2 - 1
);
particles.vertices.push(particle);
}
const particleSystem = new THREE.Points(particles, pMaterial);
scene.add(particleSystem);
function animate() {
requestAnimationFrame(animate);
for (let i = 0; i < particleCount; i++) {
const particle = particles.vertices[i];
particle.y -= 0.01;
particle.x += Math.random() * 0.01 - 0.005;
particle.z += Math.random() * 0.01 - 0.005;
if (particle.y < -1) {
particle.y = 1;
}
}
particles.verticesNeedUpdate = true;
renderer.render(scene, camera);
}
animate();
</script>
</body>
</html>
```
阅读全文