Реалізація побудови 3D-сітки оточення (Scene Reconstruction) в AR
Scene Reconstruction — це не просто "AR бачить підлогу". Це живий меш оточення, який ARKit оновлює в реальному часі по мірі руху камери. ARMeshAnchor накопичує геометрію кімнати, поверхні класифікуються, а додаток отримує дані, з якими можна працювати: детектувати перешкоди, будувати навігаційні графи, запускати фізичну симуляцію.
Реалізувати це так, щоб не убити продуктивність — окремаяя задача.
Архітектура меша та головні ловушки
ARMeshGeometry зберігає вершини, нормалі та індекси трикутників. Оновлюється через делегат session(_:didUpdate:) — кожен кадр ARKit може надсилати десятки оновлених ARMeshAnchor. Наївна реалізація, яка на кожний update перестворює MeshResource або SCNGeometry, убиває main thread за секунди.
Правильний підхід: оновлюємо меш лише для змінених анкорів, використовуємо MDLMesh як проміжний формат та передаємо дані в Metal буфери напрямку. У RealityKit це виглядає так:
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
for anchor in anchors.compactMap({ $0 as? ARMeshAnchor }) {
updateMeshVisualization(for: anchor)
}
}
func updateMeshVisualization(for anchor: ARMeshAnchor) {
let geometry = anchor.geometry
// Працюємо з geometry.vertices, geometry.faces напрямку
// Не створюємо новий MeshResource кожен раз — патчимо існуючий
}
Друга ловушка — класифікація поверхонь. ARMeshClassification дає: .floor, .ceiling, .wall, .door, .window, .seat, .table, .none. Але класифікація працює тільки при sceneReconstruction = .meshWithClassification та тільки на пристроях з LiDAR. Без перевірки ARWorldTrackingConfiguration.supportsSceneReconstruction(.meshWithClassification) — краш або мовчазне ігнорування.
Третя — координати меша у світовому просторі. ARMeshGeometry.vertices дають локальні координати відносно ARMeshAnchor.transform. Щоб отримати світові координати, потрібно помножити кожну вершину на матрицю трансформації анкора. Забули — меш рендерится у неправильному місці.
Як ми будуємо Scene Reconstruction
Базовий стек: ARKit 5+ + RealityKit 2 + Metal. SceneKit не використовуємо для меша — він не оптимізований під динамічні геометрії.
Настройка сесії:
let config = ARWorldTrackingConfiguration()
config.sceneReconstruction = .meshWithClassification
arView.debugOptions = [.showSceneUnderstanding] // для відладки
arView.session.run(config)
Для візуалізації меша у режимі відладки рисуємо wireframe через arView.debugOptions. У production видимість меша відключаємо, але використовуємо його дані для:
- Окклюзії — об'єкти за стінами не видні
-
Фізики —
CollisionComponentвзаємодіє з реальною геометрією - Raycast — точне попадання в реальні поверхні, не тільки у площини
Кейс із практики: навігаційне AR-додаток для складу. Потрібно було детектувати перешкоди (стеллажі, паллети) та будувати маршрут. Використовували Scene Reconstruction для побудови occupancy grid: кожну вершину меша з класифікацією .none (нерозпізнаний об'єкт) додавали у граф перешкод. NavMesh оновлювався кожні 2 секунди — баланс між актуальністю та навантаженням на CPU. На iPad Pro M2 це утримує 60 FPS без просадок.
Fallback та діагностика
На нон-LiDAR пристроях Scene Reconstruction недоступний. Пропонуємо деградацію до plane detection з manual mesh capture через ARPlaneAnchor. Гірше, але краще чим порожній екран.
Для діагностики якості меша — ARView.debugOptions.insert(.showSceneUnderstanding): зелений wireframe показує, що ARKit бачить. Корисно при тестуванні у нестандартних умовах (глянцеві підлоги, дзеркала — LiDAR працює погано через відбиття).
Сроки
Базова інтеграція з візуалізацією меша — 1–2 тижні. Якщо потрібні класифікація поверхонь, фізичні колізії та навігація на основі меша — 4–6 тижнів. Вартість розраховується після детального обговорення вимог.







