Frustum culling — это процесс отбраковки объектов сцены, которые находятся вне видимого объёма камеры (frustum), чтобы снизить нагрузку на GPU и увеличить производительность. В Three.js фрустум задаётся с помощью перспективной или ортографической камеры и представляет собой усечённую пирамиду, ограничивающую видимую область сцены.
Three.js по умолчанию выполняет автоматическое отсечение
объектов, используя свойство frustumCulled
объектов THREE.Object3D.
const mesh = new THREE.Mesh(geometry, material);
mesh.frustumCulled = true; // Включено по умолчанию
scene.add(mesh);
Механизм работы:
geometry.boundingSphere) на пересечение с фрустумом.Важно: для корректного отсечения геометрия должна иметь рассчитанную границу:
geometry.computeBoundingSphere();
Без этого Three.js может некорректно определять видимость объекта.
Three.js использует простые геометрические объёмы для быстрой проверки:
Box3) — прямоугольная
рамка по осям XYZ. Более точная, но требует ручной проверки.geometry.computeBoundingBox();
const boundingBox = geometry.boundingBox;
Для сложных объектов можно комбинировать bounding sphere и bounding box для оптимизации.
Ручное отсечение позволяет контролировать видимость объектов вне
автоматического процесса. Для этого используется класс
THREE.Frustum и матрица камеры
camera.projectionMatrix вместе с
camera.matrixWorldInverse.
Пример:
const frustum = new THREE.Frustum();
const cameraViewProjectionMatrix = new THREE.Matrix4();
camera.updateMatrixWorld(); // Обновление матрицы мира камеры
cameraViewProjectionMatrix.multiplyMatrices(
camera.projectionMatrix,
camera.matrixWorldInverse
);
frustum.setFromProjectionMatrix(cameraViewProjectionMatrix);
scene.traverse((object) => {
if (object.isMesh) {
object.visible = frustum.intersectsObject(object);
}
});
Пояснения:
camera.matrixWorldInverse — обратная матрица мира
камеры.frustum.setFromProjectionMatrix создаёт фрустум для
проверки видимости.frustum.intersectsObject(object) проверяет,
пересекается ли объект с фрустумом. Возвращает true или
false.object.visible управляет рендерингом
вручную.boundingSphere или
boundingBox.geometry.computeBoundingSphere(); // после трансформаций
Группировка объектов: Объекты, движущиеся
вместе, можно объединять в THREE.Group и отсекать сразу всю
группу, снижая количество проверок.
Использование LOD (Level of Detail): Для дальних объектов применять простые модели или отключать их полностью через culling.
frustumCulled = true для объектов, не
требующих полного контроля.THREE.Frustum.| Метод / Свойство | Назначение |
|---|---|
object.frustumCulled |
Включает/выключает автоматическое отсечение объекта |
geometry.computeBoundingSphere() |
Вычисляет сферу для culling |
geometry.computeBoundingBox() |
Вычисляет bounding box для ручного отсечения |
THREE.Frustum() |
Создаёт объект фрустума для проверки видимости |
frustum.setFromProjectionMatrix(matrix) |
Устанавливает фрустум из матрицы камеры |
frustum.intersectsObject(object) |
Проверяет, пересекается ли объект с фрустумом |
object.visible |
Управляет видимостью объекта при ручном culling |
Автоматическое и ручное frustum culling в Three.js позволяет эффективно управлять рендерингом, снижать нагрузку на графический процессор и поддерживать высокую частоту кадров даже в сложных сценах с большим количеством объектов.