Estoy tratando de crear una esfera con partículas flotando al azar en su superficie. Se moverá dependiendo de la posición en mousemove. algo como esto
Extrañamente, solo muestra una partícula en el lienzo. Estoy depurando con console.log(vertices)
, pero muestra claramente todos los vertices
de la matriz.
El problema es con tu bucle. Está asignando un valor a theta
y phi
solo una vez fuera de su ciclo, luego le da el mismo valor a los 1600 vértices:
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); }
Cuando use console.log(vertices)
, mire los valores x, y, z
y verá que todos se repiten.
Lo que debes hacer es reasignar un nuevo theta
y un nuevo phi
dentro del ciclo, para que cada vértice obtenga una posición única:
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); }
Tampoco necesita crear un THREE.Vector3()
en cada iteración, es bastante ineficiente crear 1600 Vector3
s solo para descartarlos de inmediato. En su lugar, puede reutilizar las mismas variables x, y, z
para evitar todos esos costos de construcción de objetos.
Consulte aquí para ver una demostración funcional de su ejemplo. También reduje el tamaño del punto a 1.
Solo un pequeño comentario, no la respuesta (todas las felicitaciones a @Marquizzo)
Desde r133
, existe un método .randomDirection()
de THREE.Vector3()
, que nos ayuda a establecer puntos en una esfera de una manera más conveniente.
Por lo tanto, todo el código para crear instancias de partículas es:
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);