Я пытаюсь создать сферу с частицами, случайно плавающими на ее поверхности. Он будет двигаться в зависимости от положения при движении мыши. что-то вроде этого
Как ни странно, на холсте отображается только одна частица. Я отлаживаю с помощью console.info(vertices)
, но он ясно показывает все vertices
в массиве.
Проблема в вашей петле. Вы присваиваете значение theta
и phi
только один раз вне цикла, затем вы присваиваете одинаковое значение всем 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.info(vertices)
, посмотрите на значения x, y, z
, и вы увидите, что все они повторяются.
Что вам нужно сделать, так это переназначить новый 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
только для того, чтобы сразу же отбросить их. Вместо этого вы можете повторно использовать одни и те же переменные x, y, z
, чтобы избежать всех этих затрат на создание объекта.
См. здесь рабочую демонстрацию вашего примера. Я также уменьшил размер точки до 1.
Просто небольшое замечание, а не ответ (спасибо @Marquizzo)
Поскольку r133
, существует метод .randomDirection()
of THREE.Vector3()
, который помогает нам расставлять точки на сфере более удобным способом.
Таким образом, весь код для создания экземпляров частиц:
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);