Реализация AR-размещения 3D-объектов на плоскости
Мы в TrueTech регулярно решаем эту задачу для заказчиков из мебельного и ритейл-сектора. Поставить 3D-модель на обнаруженную плоскость стабильно — не один вечер работы. Объект должен стоять ровно при движении камеры, не «плыть» при смене освещения, адекватно масштабироваться и не утопать в поверхности. Мы предлагаем реализацию под ключ: от подбора формата модели до финальной интеграции в ваше приложение. В одном из проектов для мебельного ритейла мы столкнулись с проблемой «проваливания» объекта в плоскость при быстром движении камеры. Решением стало использование ARAnchor с динамическим смещением по нормали на 2 мм — это исключило Z-борьбу при любом освещении.
Форматы 3D-моделей и оптимизация для AR
Стандарт для мобильного AR — USDZ (iOS/RealityKit) и GLB/GLTF (ARCore/кросс-платформенно). Типичная ошибка: брать модель без оптимизации и пытаться грузить её в AR. Полигональность 500k треугольников, текстуры 4096×4096 без mip-mapping — гарантированный FPS провал на устройствах до A13.
Целевые параметры для мобильного AR:
| Тип объекта | Полигоны | Текстуры | Размер GLB |
|---|---|---|---|
| Небольшой предмет (стул, светильник) | до 30k | 1024×1024 | до 5 МБ |
| Средний объект (диван, стол) | до 80k | 2048×2048 | до 15 МБ |
| Крупный (комплект мебели, кухня) | до 200k | 2048×2048 | до 40 МБ |
Компрессия: KTX2 + Basis Universal для GLB, HEIC-текстуры в USDZ. В RealityKit — Reality Composer Pro (Xcode 15+) для запекания PBR-материалов прямо в .reality формат. Для Android используйте Android Studio с ARCore SDK 1.30+ для конвертации GLB.
Почему Raycast лучше hitTest для размещения?
С ARKit 4+ и ARCore 1.18+ предпочтительный метод определения точки размещения — Raycast. Он возвращает ARRaycastResult с target: .existingPlaneGeometry или .estimatedPlane. existingPlaneGeometry использует уже детектированную геометрию — точность в 2 раза выше, чем у устаревшего hitTest. Apple рекомендует raycast как основной метод (см. документацию ARKit). Более того, hitTest был объявлен устаревшим в iOS 14, и его использование может привести к отклонению приложения из-за требований App Store Review Guidelines (раздел 4.2: минимальная функциональность).
Пример на Swift:
let query = arView.makeRaycastQuery(
from: arView.center,
allowing: .existingPlaneGeometry,
alignment: .horizontal
)
let results = arView.session.raycast(query)
if let first = results.first {
placeEntity(at: first.worldTransform)
}
Для ARCore — Session.createRaycastQuery() + Frame.raycast() даёт более стабильный результат на краях плоскостей.
Как стабилизировать объект после размещения?
После первого размещения объект не должен «гулять» при движении камеры. Стандартный подход — привязка к AnchorEntity через ARAnchor:
let anchor = ARAnchor(transform: worldTransform)
arView.session.add(anchor: anchor)
let anchorEntity = AnchorEntity(anchor: anchor)
anchorEntity.addChild(modelEntity)
arView.scene.addAnchor(anchorEntity)
Явный ARAnchor фиксирует позицию, и объект не обновляется вместе с уточнением плоскости. Без этого он смещается первые 10–15 секунд сессии, пока ARKit уточняет геометрию. Дополнительно можно применить фильтрацию Калмана к позиции якоря, если объект всё же дрожит.
Тени и физическое освещение
AR-объект без тени выглядит «летящим». В RealityKit тень создаётся установкой castsShadow = true у entity — contact shadow рендерится автоматически. В SceneKit для этого нужен directional light с castsShadow = true. Важно: при использовании environment texturing (ARKit, A12+) объекты получают отражения реального окружения. Металлические поверхности отражают интерьер — без этого хромированный предмет выглядит пластиковым. Включите environmentTexturing = .automatic в ARWorldTrackingConfiguration.
Какие жесты поддерживаются для манипуляции объектом?
После размещения пользователь должен иметь возможность перемещать, вращать и масштабировать объект. В RealityKit жесты добавляются в одну строку:
arView.installGestures([.translation, .rotation, .scale], for: entity)
Для кастомного управления используйте UILongPressGestureRecognizer с непрерывным raycast — это даёт больший контроль над чувствительностью. При реализации вращения обязательно ограничьте ось Y: используйте simd_quatf(angle:axis:) только вокруг вертикальной оси, иначе объект «заваливается» при неточном жесте. На Android аналогично: GestureRecognizer из Sceneform или ArGestureRecognizer в ARCore.
Как тестировать AR-размещение на разных устройствах?
Критично протестировать на нескольких поколениях iPhone и Android-устройствах. Например, на iPhone XR (A12) raycast работает стабильно, но environment texturing потребляет дополнительную память — может проседать FPS при высокополигональных моделях. Рекомендуем использовать TestFlight для iOS и внутреннее тестирование Google Play для Android — это позволяет выявить проблемы с глубиной (Z-fighting) на разных версиях ARCore.
Что входит в работу
| Этап | Результат |
|---|---|
| Анализ модели и требований | Выбор формата, оптимизация полигонов и текстур |
| Разработка размещения | Raycast, anchor, стабилизация, тени |
| Реализация жестов | Перемещение, вращение, масштабирование |
| Тестирование на устройствах | Проверка стабильности на разных версиях iOS/Android |
| Интеграция в приложение | Документация, доступы к репозиторию, обучение команды |
Наш опыт — более 20 успешных проектов в мобильной AR-разработке. Свяжитесь с нами для оценки вашего проекта — реализуем под ключ за 2–3 недели. Получите консультацию без обязательств.







