Интеграция ARKit в iOS-приложение
ARKit 6 — не просто наложение 3D-объектов на камеру. Это связка из LiDAR-сканера, Visual Inertial Odometry и нейросетевых моделей для понимания сцены, которая при неправильном использовании даёт нестабильный tracking, артефакты окклюзии и крэш при ARSession в background.
Что ломается чаще всего
Tracking падает при плохом освещении. ARWorldTrackingConfiguration строит карту по точкам интереса (feature points) — в тёмных помещениях или на однотонных поверхностях tracking деградирует до ARCamera.TrackingState.limited(.insufficientFeatures). Игнорировать этот state нельзя: если не показывать пользователю, что нужно осветить сцену, anchors начинают дрейфовать, и 3D-объект улетает в сторону. Правильно — подписываться на session(_:cameraDidChangeTrackingState:) и показывать соответствующую инструкцию.
Плоскости обнаруживаются с задержкой. ARPlaneDetection.horizontal находит пол за 2–4 секунды при хорошем освещении. Если пользователь пытается разместить объект раньше — промах. Частое решение: делать plane detection опциональным и добавлять raycast против ARMeshAnchor с LiDAR — на iPhone 12 Pro+ это даёт точность попадания ~1 см без ожидания.
Окклюзия работает только с LiDAR. ARView.environment.sceneUnderstanding.options с .occlusion работает исключительно на устройствах с LiDAR (Pro-серия с iPhone 12). На iPhone без LiDAR объект всегда поверх реального мира. Нужно чекать ARWorldTrackingConfiguration.supportsSceneReconstruction(.mesh) при старте и деградировать gracefully.
Стек и подходы
Для большинства AR-задач используем RealityKit поверх ARKit — он абстрагирует низкоуровневый рендеринг через Metal и поддерживает физику, анимации USDZ, окклюзию. Для сложных кейсов с кастомными шейдерами или интеграцией с SceneKit-контентом работаем напрямую через ARSCNView.
Базовая конфигурация сессии под размещение объектов:
let config = ARWorldTrackingConfiguration()
config.planeDetection = [.horizontal, .vertical]
config.environmentTexturing = .automatic
if ARWorldTrackingConfiguration.supportsSceneReconstruction(.mesh) {
config.sceneReconstruction = .meshWithClassification
}
arView.session.run(config, options: [.resetTracking, .removeExistingAnchors])
environmentTexturing = .automatic включает захват кубической карты окружения и применяет её к PBR-материалам — объекты отражают реальный свет сцены.
Размещение объекта по raycast (правильный современный способ, не hitTest который deprecated):
let query = arView.makeRaycastQuery(
from: arView.center,
allowing: .estimatedPlane,
alignment: .horizontal
)
if let query = query,
let result = arView.session.raycast(query).first {
let anchor = ARAnchor(name: "placed-object", transform: result.worldTransform)
arView.session.add(anchor: anchor)
let modelEntity = try! ModelEntity.loadModel(named: "model.usdz")
let anchorEntity = AnchorEntity(anchor: anchor)
anchorEntity.addChild(modelEntity)
arView.scene.addAnchor(anchorEntity)
}
Работа с Image Tracking
ARImageTrackingConfiguration с maximumNumberOfTrackedImages = 4 — для маркерного AR. Референсные изображения загружаем из ARReferenceImage с физическим размером:
let referenceImage = ARReferenceImage(
cgImage,
orientation: .up,
physicalWidth: 0.15 // 15 см в реальном мире
)
config.trackingImages = [referenceImage]
physicalWidth критичен — ARKit использует его для вычисления дистанции и масштаба. Неверный размер = объект висит не там где надо.
Face Tracking и TrueDepth
ARFaceTrackingConfiguration работает только на устройствах с TrueDepth-камерой (Face ID). Доступно 52 blend shape коэффициента через ARFaceAnchor.blendShapes — от .jawOpen до .eyeBlinkLeft. На этом строим виртуальные примерки, AR-аватары и Liveness Detection.
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
guard let faceAnchor = anchors.first as? ARFaceAnchor else { return }
let jawOpen = faceAnchor.blendShapes[.jawOpen]?.floatValue ?? 0
// Управляем анимацией персонажа
}
Производительность и профилирование
ARKit + RealityKit нагружают GPU и CPU одновременно. Инструменты диагностики: Xcode's Reality Composer Pro для превью сцены, GPU Frame Capture для анализа draw calls, Metal System Trace в Instruments для диагностики GPU bubbles.
Типичные узкие места:
- USDZ с > 100K полигонов на середнячке — просадка до 30 FPS
- Несколько
ModelEntityбез инстансинга копируют геометрию в памяти -
arView.renderOptions— отключение.disableDepthOfFieldи.disableMotionBlurдаёт +15% FPS на старых устройствах
Этапы работы
Аудит требований: какие устройства поддерживать, нужен ли LiDAR, тип tracking (world/image/face/body). Проектирование деградации на несовместимых устройствах. Разработка AR-ядра с сессией и плейсментом. Интеграция 3D-контента (конвертация из FBX/OBJ в USDZ через Reality Converter). Тестирование на физических устройствах — симулятор AR не поддерживает. Оптимизация производительности под целевые модели iPhone/iPad.
Сроки
Базовая интеграция ARKit с размещением USDZ-объекта по плоскости: 3–5 дней. Image tracking с маркерами и наложением контента: 4–7 дней. Комплексное решение с face tracking, окклюзией LiDAR и кастомными шейдерами Metal: 3–6 недель. Стоимость зависит от сложности 3D-контента и требований к поддерживаемым устройствам.







