В Three.js стандартные геометрические объекты, такие как
BoxGeometry, SphereGeometry или
PlaneGeometry, предоставляют удобные методы для быстрого
создания сцен. Однако для более сложных или нестандартных форм
необходима работа с буферной геометрией
(BufferGeometry) и ручное определение вершин, нормалей и
координат текстур с помощью массивов типа Float32Array. Это
дает полный контроль над структурой объекта и позволяет оптимизировать
производительность.
BufferGeometry состоит из атрибутов
(attributes), каждый из которых представляет собой массив
данных:
[x1, y1, z1, x2, y2, z2, ...].[u1, v1, u2, v2, ...].Атрибуты создаются с помощью Float32BufferAttribute:
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([
0, 0, 0,
1, 0, 0,
0, 1, 0
]);
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
В примере массив vertices содержит три вершины
треугольника, каждая из которых описана тремя числами (x, y, z).
Использование атрибута index позволяет избежать
дублирования вершин при построении сложной геометрии. Индексы
указывают, какие вершины формируют треугольники:
const indices = new Uint16Array([0, 1, 2]);
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
Если объект содержит более 65535 вершин, следует использовать
Uint32Array вместо Uint16Array.
Для корректного освещения каждой вершины необходимо задать нормали. Они указывают направление, перпендикулярное поверхности:
const normals = new Float32Array([
0, 0, 1,
0, 0, 1,
0, 0, 1
]);
geometry.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3));
Нормали могут быть рассчитаны вручную или автоматически с помощью
метода computeVertexNormals():
geometry.computeVertexNormals();
Атрибут uv определяет, как текстура проецируется на
поверхность объекта. Значения находятся в диапазоне
[0, 1]:
const uvs = new Float32Array([
0, 0,
1, 0,
0, 1
]);
geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));
Комбинируя uv с материалами
MeshBasicMaterial или MeshStandardMaterial,
можно создавать реалистичные текстурированные поверхности.
Для сложных моделей вершины, нормали и UV-координаты создаются
программно. Например, генерация плоскости размером
width x height с segmentsX и
segmentsY:
const width = 2;
const height = 2;
const segmentsX = 4;
const segmentsY = 4;
const vertices = [];
const normals = [];
const uvs = [];
const indices = [];
for (let y = 0; y <= segmentsY; y++) {
for (let x = 0; x <= segmentsX; x++) {
const posX = (x / segmentsX - 0.5) * width;
const posY = (y / segmentsY - 0.5) * height;
vertices.push(posX, posY, 0);
normals.push(0, 0, 1);
uvs.push(x / segmentsX, y / segmentsY);
}
}
for (let y = 0; y < segmentsY; y++) {
for (let x = 0; x < segmentsX; x++) {
const a = x + (segmentsX + 1) * y;
const b = x + (segmentsX + 1) * (y + 1);
const c = (x + 1) + (segmentsX + 1) * (y + 1);
const d = (x + 1) + (segmentsX + 1) * y;
indices.push(a, b, d);
indices.push(b, c, d);
}
}
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
geometry.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3));
geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));
geometry.setIndex(indices);
Такой подход позволяет создавать сетку с произвольным разрешением, управлять деформациями и создавать процедурные формы.
geometry.attributes.position.needsUpdate = true после
изменения вершин.vertex shader).Работа с Float32Array в Three.js
предоставляет максимальную гибкость при создании
геометрии, позволяя реализовать любые формы и оптимизировать
сцены для WebGL без ограничений готовых примитивов.