three.js 场景中仅显示一个粒子

only one particle showing in the scene with three.js

我正在尝试创建一个粒子随机漂浮在其表面的球体。它会移动取决于 mousemove 上的位置。 像这样

奇怪的是,canvas上只显示一个粒子。我正在使用 console.log(vertices) 进行调试,但它清楚地显示了数组中的所有 vertices

My code in CodeSandBox

问题出在你的循环上。您只在循环外为 thetaphi 赋值一次,然后为所有 1600 个顶点赋予相同的值:

const theta = Math.acos(THREE.Math.randFloatSpread(2));
const phi = THREE.Math.randFloatSpread(360);

for (let i = 0; i < 1600; i++) {
  const vertex = new THREE.Vector3();

  vertex.x = distance * Math.sin(theta) * Math.cos(phi);
  vertex.y = distance * Math.sin(theta) * Math.sin(phi);
  vertex.z = distance * Math.cos(theta);

  vertices.push(vertex.x, vertex.y, vertex.z);
}

当您使用 console.log(vertices) 时,查看 x, y, z 值,您会发现它们全部重复。

你应该做的是re-assign一个新的theta和一个新的phi循环中,所以每个顶点都有一个唯一的位置:

let theta, phi;
let x, y, z;

for (let i = 0; i < 1600; i++) {
  theta = Math.acos(THREE.Math.randFloatSpread(2));
  phi = THREE.Math.randFloatSpread(360);

  x = distance * Math.sin(theta) * Math.cos(phi);
  y = distance * Math.sin(theta) * Math.sin(phi);
  z = distance * Math.cos(theta);

  vertices.push(x, y, z);
}

您也不需要在每次迭代时创建一个 THREE.Vector3(),创建 1600 个 Vector3 只是为了立即丢弃是非常低效的。相反,您可以 re-use 相同的 x, y, z 变量来避免所有这些对象构造成本。

See here for a working demo 你的例子。我还将磅值缩小到 1。

只是一个小评论,不是答案(@Marquizzo 的所有荣誉)

r133开始,有了THREE.Vector3()的方法.randomDirection(),可以帮助我们更方便地在球体上设置点。

因此,粒子实例化的全部代码为:

    const distance = Math.min(200, window.innerWidth / 16);
    let vertices = new Array(1600).fill().map((v) => {
      return new THREE.Vector3().randomDirection().setLength(distance);
    });
    const geometry = new THREE.BufferGeometry().setFromPoints(vertices);
    const material = new THREE.PointsMaterial({ color: 0xffffff, size: 1 });
    const particles = new THREE.Points(geometry, material);

Demo