BufferGeometry является основой для всех геометрических
объектов в Three.js и представляет собой эффективный способ хранения
вершин, нормалей, цветов и других атрибутов. В отличие от устаревшего
Geometry, BufferGeometry работает напрямую с
массивами данных, что позволяет значительно снизить нагрузку на CPU и
повысить производительность рендеринга.
Ключевые аспекты:
BufferAttribute или
InterleavedBufferAttribute.Float32Array, Uint16Array и т.д.).position, normal, color,
uv и др.index.Атрибуты хранятся в объекте attributes, где ключ — имя
атрибута, а значение — объект BufferAttribute. Основные
атрибуты:
Пример создания простого атрибута:
const vertices = new Float32Array([
0, 0, 0,
1, 0, 0,
0, 1, 0
]);
const positionAttribute = new THREE.BufferAttribute(vertices, 3);
geometry.setAttribute('position', positionAttribute);
Здесь каждый набор из трёх чисел соответствует одной вершине. Второй параметр указывает размерность (3 для 3D координат).
Использование индексов позволяет избежать дублирования вершин,
особенно в сложных моделях. Атрибут index хранит массив
индексов вершин:
const indices = new Uint16Array([0, 1, 2]);
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
Индексированная геометрия уменьшает объём памяти и ускоряет рендеринг, так как GPU повторно использует уже переданные вершины.
Для оптимизации больших массивов данных используется InterleavedBuffer, где разные атрибуты хранятся в одном массиве:
const array = new Float32Array([
0, 0, 0, 1, 0, 0, // vertex1: position(x,y,z) + color(r,g,b)
1, 0, 0, 0, 1, 0, // vertex2
]);
const interleavedBuffer = new THREE.InterleavedBuffer(array, 6); // 6 значений на вершину
geometry.setAttribute('position', new THREE.InterleavedBufferAttribute(interleavedBuffer, 3, 0));
geometry.setAttribute('color', new THREE.InterleavedBufferAttribute(interleavedBuffer, 3, 3));
Преимущества: сокращение числа отдельных массивов, уменьшение overhead при передаче данных на GPU.
BufferGeometry напрямую отображается в Vertex
Buffer Object (VBO) на GPU. Каждое обновление атрибута требует
уведомления GPU через needsUpdate:
geometry.attributes.position.needsUpdate = true;
Для динамических объектов рекомендуется использовать:
positionAttribute.setUsage(THREE.DynamicDrawUsage);
Это указывает WebGL, что буфер будет часто изменяться, оптимизируя пересылку данных.
Простая треугольная сетка:
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([
-1, -1, 0,
1, -1, 0,
0, 1, 0
]);
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.computeVertexNormals();
const material = new THREE.MeshStandardMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
Смешение нескольких атрибутов:
const positions = new Float32Array([...]);
const colors = new Float32Array([...]);
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
material.vertexColors = true;
Такой подход позволяет визуализировать сложные эффекты, управляя цветами вершин напрямую, без текстур.
BufferGeometry обеспечивает основу для любой сложной
3D-сцены в Three.js. Понимание структуры атрибутов, индексов и работы с
GPU критично для оптимизации производительности и создания
высокоэффективных визуализаций.