探索 Three.js 中的粒子系统:创建星空、烟雾与特效

在这里插入图片描述

粒子系统是一种强大的工具,可以用来模拟自然现象,比如星空、烟雾、火焰、雪花等。Three.js 提供了灵活的粒子系统支持,结合材质、纹理和动画,可以轻松实现令人惊艳的特效。


一、粒子系统的基础概念

在 Three.js 中,粒子系统是通过 Points 类实现的,它包含以下主要组件:

  1. 几何体(Geometry):定义粒子的位置。
  2. 材质(Material):控制粒子的外观,比如颜色、透明度。
  3. 点云(Points):将几何体和材质结合,渲染粒子。

二、创建星空效果

星空是粒子系统的经典应用之一,模拟点状粒子分布在三维空间中,生成随机闪烁的效果。

1. 初始化场景

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);

2. 创建星星粒子

const starGeometry = new THREE.BufferGeometry();
const starCount = 1000; // 星星数量

// 定义每个星星的随机位置
const positions = new Float32Array(starCount * 3);
for (let i = 0; i < starCount * 3; i++) {
    positions[i] = (Math.random() - 0.5) * 10; // 随机分布在立方体空间
}

// 添加位置到几何体
starGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));

// 使用基础点材质
const starMaterial = new THREE.PointsMaterial({
    color: 0xffffff,
    size: 0.05,
});

// 创建点云
const stars = new THREE.Points(starGeometry, starMaterial);
scene.add(stars);

3. 动画星空

function animate() {
    requestAnimationFrame(animate);
    stars.rotation.y += 0.001; // 添加旋转效果
    renderer.render(scene, camera);
}
animate();

三、实现烟雾效果

烟雾粒子通常通过半透明的纹理叠加实现,需要粒子平滑过渡的视觉效果。

1. 加载烟雾纹理

下载或使用一个半透明的烟雾纹理图片(如 PNG 格式),并加载到材质中:

const textureLoader = new THREE.TextureLoader();
const smokeTexture = textureLoader.load('smoke.png'); // 替换为实际路径

2. 创建烟雾粒子系统

const smokeParticles = [];
const smokeMaterial = new THREE.PointsMaterial({
    map: smokeTexture,
    transparent: true,
    opacity: 0.5,
    depthWrite: false, // 避免深度冲突
});

// 随机分布烟雾粒子
for (let i = 0; i < 50; i++) {
    const smokeGeometry = new THREE.BufferGeometry();
    const position = new Float32Array([
        (Math.random() - 0.5) * 10,
        (Math.random() - 0.5) * 10,
        (Math.random() - 0.5) * 10,
    ]);
    smokeGeometry.setAttribute('position', new THREE.BufferAttribute(position, 3));
    const smoke = new THREE.Points(smokeGeometry, smokeMaterial);
    smokeParticles.push(smoke);
    scene.add(smoke);
}

3. 动态模拟烟雾

function animateSmoke() {
    smokeParticles.forEach((smoke) => {
        smoke.position.y += 0.01; // 上升效果
        if (smoke.position.y > 5) smoke.position.y = -5; // 循环
    });
    renderer.render(scene, camera);
    requestAnimationFrame(animateSmoke);
}
animateSmoke();

四、制作炫酷粒子特效

粒子特效可以结合颜色变化、运动轨迹和自定义着色器来实现。

1. 彩色粒子系统

const colorGeometry = new THREE.BufferGeometry();
const colorCount = 500;

// 定义位置与颜色
const positions = new Float32Array(colorCount * 3);
const colors = new Float32Array(colorCount * 3);
for (let i = 0; i < colorCount; i++) {
    const x = (Math.random() - 0.5) * 10;
    const y = (Math.random() - 0.5) * 10;
    const z = (Math.random() - 0.5) * 10;

    positions.set([x, y, z], i * 3);

    const r = Math.random();
    const g = Math.random();
    const b = Math.random();
    colors.set([r, g, b], i * 3);
}

colorGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
colorGeometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));

// 设置材质支持顶点颜色
const colorMaterial = new THREE.PointsMaterial({
    vertexColors: true,
    size: 0.1,
});

const colorParticles = new THREE.Points(colorGeometry, colorMaterial);
scene.add(colorParticles);

五、优化粒子系统性能

粒子系统可能会消耗大量性能,以下是一些优化方法:

  1. 减少粒子数量:根据场景实际需求调整粒子数量。
  2. 使用纹理代替复杂几何体:例如烟雾使用 PNG 纹理。
  3. 批量渲染:使用 InstancedMesh 处理重复对象。
  4. LOD(Level of Detail):对远处的粒子减少渲染精度。
  5. GPU 着色器:复杂效果可通过自定义 Shader 实现高效渲染。

总结

Three.js 粒子系统为 3D 场景提供了丰富的动态效果,适用于星空、烟雾、火焰等多种特效场景。通过材质、纹理和动画的组合,甚至可以实现类似 AAA 游戏中的炫酷效果。快动手尝试,把你的项目变得更加吸引人吧! 🚀

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐