80 lines
2.2 KiB
JavaScript
80 lines
2.2 KiB
JavaScript
import * as THREE from 'three';
|
|
|
|
let dustParticles = null;
|
|
let dustPositions = null;
|
|
let dustVelocities = null;
|
|
const DUST_COUNT = 600;
|
|
|
|
export function initEffects(scene) {
|
|
initDustMotes(scene);
|
|
}
|
|
|
|
function initDustMotes(scene) {
|
|
const geo = new THREE.BufferGeometry();
|
|
const positions = new Float32Array(DUST_COUNT * 3);
|
|
const colors = new Float32Array(DUST_COUNT * 3);
|
|
const velocities = new Float32Array(DUST_COUNT);
|
|
|
|
for (let i = 0; i < DUST_COUNT; i++) {
|
|
positions[i * 3] = (Math.random() - 0.5) * 22;
|
|
positions[i * 3 + 1] = Math.random() * 10;
|
|
positions[i * 3 + 2] = (Math.random() - 0.5) * 16 - 2;
|
|
velocities[i] = 0.008 + Math.random() * 0.012;
|
|
|
|
const roll = Math.random();
|
|
if (roll < 0.6) {
|
|
colors[i * 3] = 0.9 + Math.random() * 0.1;
|
|
colors[i * 3 + 1] = 0.7 + Math.random() * 0.2;
|
|
colors[i * 3 + 2] = 0.3 + Math.random() * 0.3;
|
|
} else {
|
|
const b = 0.3 + Math.random() * 0.5;
|
|
colors[i * 3] = 0;
|
|
colors[i * 3 + 1] = b;
|
|
colors[i * 3 + 2] = 0;
|
|
}
|
|
}
|
|
|
|
geo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
|
|
geo.setAttribute('color', new THREE.BufferAttribute(colors, 3));
|
|
dustPositions = positions;
|
|
dustVelocities = velocities;
|
|
|
|
const mat = new THREE.PointsMaterial({
|
|
size: 0.06,
|
|
vertexColors: true,
|
|
transparent: true,
|
|
opacity: 0.55,
|
|
sizeAttenuation: true,
|
|
});
|
|
|
|
dustParticles = new THREE.Points(geo, mat);
|
|
scene.add(dustParticles);
|
|
}
|
|
|
|
export function updateEffects(time) {
|
|
if (!dustParticles) return;
|
|
const t = time * 0.001;
|
|
|
|
for (let i = 0; i < DUST_COUNT; i++) {
|
|
dustPositions[i * 3 + 1] += dustVelocities[i];
|
|
dustPositions[i * 3] += Math.sin(t * 0.5 + i * 0.1) * 0.002;
|
|
|
|
if (dustPositions[i * 3 + 1] > 10) {
|
|
dustPositions[i * 3 + 1] = 0;
|
|
dustPositions[i * 3] = (Math.random() - 0.5) * 22;
|
|
dustPositions[i * 3 + 2] = (Math.random() - 0.5) * 16 - 2;
|
|
}
|
|
}
|
|
dustParticles.geometry.attributes.position.needsUpdate = true;
|
|
}
|
|
|
|
export function disposeEffects() {
|
|
if (dustParticles) {
|
|
dustParticles.geometry.dispose();
|
|
dustParticles.material.dispose();
|
|
dustParticles = null;
|
|
}
|
|
dustPositions = null;
|
|
dustVelocities = null;
|
|
}
|