1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
// Rain.js - 实例化渲染
const Rain = ({ count = 1000 }) => {
const meshRef = useRef();
const dummy = useMemo(() => new THREE.Object3D(), []);
const particles = useMemo(() => {
const temp = [];
for (let i = 0; i < count; i++) {
temp.push({
x: (Math.random() - 0.5) * 20,
y: Math.random() * 20 + 10,
z: (Math.random() - 0.5) * 20,
speed: Math.random() * 0.1 + 0.05,
});
}
return temp;
}, [count]);
useFrame(() => {
particles.forEach((particle, i) => {
particle.y -= particle.speed;
if (particle.y < -1) {
particle.y = 20; // 重置到顶部
}
dummy.position.set(particle.x, particle.y, particle.z);
dummy.updateMatrix();
meshRef.current.setMatrixAt(i, dummy.matrix);
});
meshRef.current.instanceMatrix.needsUpdate = true;
});
return (
<instancedMesh ref={meshRef} args={[null, null, count]}>
<cylinderGeometry args={[0.01, 0.01, 0.5, 8]} />
<meshBasicMaterial color="#87CEEB" transparent opacity={0.6} />
</instancedMesh>
);
};
|