I am trying to create a sphere with particles randomly floating on its surface. It will move depends on the position on mousemove. something like this
Strangely, it is only displaying one particle on canvas. I am debugging with console.log(vertices)
, but it clearly shows all the vertices
in the array.
Advertisement
Answer
The problem is with your loop. You’re assigning a value to theta
and phi
only once outside your loop, then you give the same value to all 1600 vertices:
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); }
When you use console.log(vertices)
, look at the x, y, z
values and you’ll see they all repeat.
What you should do is re-assign a new theta
and a new phi
inside the loop, so each vertex gets a unique position:
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); }
You also don’t need to create a THREE.Vector3()
on each iteration, it’s pretty inefficient to create 1600 Vector3
s just to be discarded immediately. Instead you can re-use the same x, y, z
variables to avoid all those object construction costs.
See here for a working demo of your example. I also scaled down the point size to 1.