diff --git a/js/globe.js b/js/globe.js index 6153a4a..fcee1e1 100644 --- a/js/globe.js +++ b/js/globe.js @@ -58,12 +58,13 @@ return 1 - Math.pow(1 - t, 3); } - // 准备粒子数据:startPositions / targetPositions / current positions / size + // 准备粒子数据:startPositions / targetPositions / current positions / size / speedFactor var geometry = new THREE.BufferGeometry(); var positions = new Float32Array(PARTICLE_COUNT * 3); var startPositions = new Float32Array(PARTICLE_COUNT * 3); var targetPositions = new Float32Array(PARTICLE_COUNT * 3); var sizes = new Float32Array(PARTICLE_COUNT); + var speedFactors = new Float32Array(PARTICLE_COUNT); // 随机在球壳表面生成点(均匀分布),作为目标位置 function randomPointOnSphere(radius) { @@ -113,6 +114,10 @@ // 粒子尺寸:每个粒子随机一个基础大小,后续在顶点着色器中再做距离衰减 // 你可以调节下方这两个数,控制整体粒子大小的分布范围 sizes[i] = 1.0 + Math.random() * 1.5; // 1.0 ~ 2.5 之间,避免大颗粒过于“糊” + + // 每个粒子的飞行速度因子:有的快、有的慢;到达目标后就“贴”在球面上不再移动 + // 例如 0.7~1.3 之间的随机值 + speedFactors[i] = 0.7 + Math.random() * 0.6; } geometry.setAttribute( @@ -234,9 +239,13 @@ var ty = targetPositions[i3 + 1]; var tz = targetPositions[i3 + 2]; - positions[i3] = sx + (tx - sx) * eased; - positions[i3 + 1] = sy + (ty - sy) * eased; - positions[i3 + 2] = sz + (tz - sz) * eased; + // 为了让每个粒子在到达球面后“贴”在球体上,而不是等所有粒子一起完成: + // 这里为每个粒子引入独立的速度因子,使其进度各不相同,并对每个粒子单独 clamp 到 1。 + var pf = Math.min(1, eased * speedFactors[i]); // 每个粒子的独立进度 0~1 + + positions[i3] = sx + (tx - sx) * pf; + positions[i3 + 1] = sy + (ty - sy) * pf; + positions[i3 + 2] = sz + (tz - sz) * pf; } geometry.attributes.position.needsUpdate = true;