При работе с большими сценами в Three.js критически важна оптимизация, особенно когда сцена содержит тысячи объектов или сложные геометрии. Одним из самых эффективных подходов является использование BVH (Bounding Volume Hierarchy) — иерархической структуры ограничивающих объёмов для ускорения операций с мешами, таких как raycasting, пересечения и столкновения.
Bounding Volume Hierarchy (BVH) — это структура данных, которая рекурсивно делит геометрию на узлы, каждый из которых ограничен простым объёмом (обычно AABB — Axis-Aligned Bounding Box).
Основные преимущества использования BVH:
Принцип построения BVH включает:
three-mesh-bvh — сторонняя библиотека для Three.js, реализующая BVH для мешей. Она позволяет ускорять:
Установка:
npm install three-mesh-bvh
Импорт в проект:
import { MeshBVH, acceleratedRaycast } from 'three-mesh-bvh';
import * as THREE from 'three';
Для ускорения raycasting у меша необходимо заменить стандартный метод
raycast на оптимизированный:
// Подключение ускоренного raycast
THREE.Mesh.prototype.raycast = acceleratedRaycast;
// Создание BVH для геометрии
const geometry = new THREE.BufferGeometry();
// ... заполняем geometry вершинами и индексами
geometry.computeBoundsTree = MeshBVH.prototype.build;
geometry.computeBoundsTree();
// Применение к мешу
const mesh = new THREE.Mesh(geometry, material);
После этого любые вызовы raycaster.intersectObject(mesh)
будут выполняться значительно быстрее, особенно на больших
геометриях.
three-mesh-bvh предоставляет опции для настройки
производительности:
Пример:
const bvh = new MeshBVH(geometry, {
maxLeafTris: 20,
lazyGeneration: false
});
geometry.boundsTree = bvh;
Для объектов, геометрия которых изменяется в процессе анимации, можно использовать методы refit или update:
// После изменения вершин
geometry.attributes.position.needsUpdate = true;
// Перестройка BVH
geometry.boundsTree.refit();
Метод refit обновляет ограничивающие объёмы без полной
перестройки дерева, что позволяет сохранять производительность при
изменении формы объекта.
С BVH raycasting становится логарифмическим по количеству треугольников, а не линейным. Пример использования:
const raycaster = new THREE.Raycaster();
raycaster.set(origin, direction);
const intersects = raycaster.intersectObject(mesh, true);
intersects.forEach(hit => {
console.log(hit.point, hit.faceIndex);
});
На больших мешах (десятки тысяч треугольников) ускорение может достигать 50–100 раз по сравнению с обычным raycasting.
Использование BVH и three-mesh-bvh в Three.js является ключевым инструментом для оптимизации сложных сцен. Эти методы позволяют эффективно работать с высокополигональными моделями, ускоряют raycasting и детекцию столкновений, делая интерактивные приложения плавными и отзывчивыми даже при больших объемах геометрии.