Інтеграція ARCore в Android-додаток
ARCore працює на 400+ моделях Android-пристроїв — і це головна складність. На Pixel 7 з тензорним чипом tracking тримається стабільно. На бюджетному Redmi з тією ж версією ARCore — площини не виявляються через слабку камеру та вібрацію від дешевого OIS. Тестувати на одному пристрої та вважати, що працює везде — помилка.
Сумісність та деградація
ARCore підтримується тільки на пристроях з офіційного списку Google. Перед запуском сесії — обов'язкова перевірка:
val availability = ArCoreApk.getInstance().checkAvailability(context)
when (availability) {
ArCoreApk.Availability.SUPPORTED_INSTALLED -> startArSession()
ArCoreApk.Availability.SUPPORTED_NOT_INSTALLED -> promptInstall()
ArCoreApk.Availability.UNSUPPORTED_DEVICE_NOT_CAPABLE -> showFallback()
else -> { /* SUPPORTED_APK_TOO_OLD, UNKNOWN_ERROR */ }
}
UNSUPPORTED_DEVICE_NOT_CAPABLE — пристрій ніколи не отримає підтримку. Показуємо fallback, не намагаємося встановити ARCore. Немає сенсу битися об цю стіну.
Архітектура AR-сесії
ARCore в Android будується навколо об'єкта Session з com.google.ar.core. Інтеграція з рендерингом — через GLSurfaceView (старий шлях) або ArSceneView з Sceneform (deprecated Google, але maintained fork). Для нових проектів беремо SceneView — активно підтримуваний fork Sceneform з Kotlin coroutines API.
// build.gradle
implementation("io.github.sceneview:arsceneview:2.0.3")
val arSceneView = binding.arSceneView
arSceneView.onSessionCreated = { session ->
session.configure(
Config(session).apply {
planeFindingMode = Config.PlaneFindingMode.HORIZONTAL_AND_VERTICAL
lightEstimationMode = Config.LightEstimationMode.ENVIRONMENTAL_HDR
depthMode = Config.DepthMode.AUTOMATIC
}
)
}
ENVIRONMENTAL_HDR — ключовий флаг для реалістичного освітлення. ARCore захоплює HDR-кубічну карту оточення та застосовує до PBR-матеріалів. Об'єкт отримує тіні та відбиття з реальної сцени.
Depth API
На пристроях з depth-сенсором (ToF-камера: Pixel 6 Pro, Samsung S21 Ultra) DepthMode.AUTOMATIC включає реальну карту глибини. На інших — ARCore генерує depth через ML-модель по одній камері. Окклюзія реальними об'єктами:
arSceneView.onSessionUpdated = { session, frame ->
if (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) {
val depthImage = frame.acquireDepthImage16Bits()
// Передаємо в шейдер для per-pixel occlusion
depthImage.close()
}
}
Не забувати .close() — Image об'єкти з ARCore тримають native memory, утечка ведє до OutOfMemoryError за хвилину активної сесії.
Plane Detection та Hit Test
Стандартне розміщення об'єкта по тапу:
arSceneView.onGestureListener = object : DefaultARSceneViewGestureListener(arSceneView) {
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
val hitResults = arSceneView.frame?.hitTest(e.x, e.y) ?: return false
val hitResult = hitResults.firstOrNull { hit ->
hit.trackable is Plane && (hit.trackable as Plane).isPoseInPolygon(hit.hitPose)
} ?: return false
val anchor = hitResult.createAnchor()
val node = ModelNode(modelFileLocation = "models/chair.glb")
node.anchor = anchor
arSceneView.addChild(node)
return true
}
}
Перевірка isPoseInPolygon важлива — hitTest може повернути точку за краєм виявленої площини, і об'єкт повиснеться в повітрі.
Augmented Images
AugmentedImageDatabase — для маркерного AR. База компілюється заранее через arcoreimg CLI (оцінює якість зображення, Score ≥ 75 для надійного tracking):
arcoreimg eval-img --input_image_path=marker.png
# Image Quality Score: 87 (acceptable range: 0-100, >= 75 recommended)
val imageDatabase = AugmentedImageDatabase(session)
val bitmap = BitmapFactory.decodeStream(assets.open("marker.png"))
imageDatabase.addImage("product-marker", bitmap, 0.10f) // 10 см фізично
config.augmentedImageDatabase = imageDatabase
Зображення з однорідними кольорами або симетричними паттернами дають низький score — ARCore не може знайти унікальні feature points. Логотипи з дрібними деталями працюють краще.
Тестування на реальних пристроях
Емулятор ARCore не дає реального трекінгу. Обов'язково тестуємо на:
- Флагманах (Pixel, Galaxy S-серія) — еталонна продуктивність
- Середньому класі (Samsung A-серія, Xiaomi Redmi Note) — реальна аудиторія
- Пристрої без depth-сенсора — проверка деградації depth API
Firebase Test Lab підтримує фізичні пристрої з ARCore — можна автоматизувати базові перевірки запуску сесії.
Терміни
Базова інтеграція ARCore з plane detection та розміщенням GLB-моделі: 3–5 днів. Augmented Images з базою маркерів та кастомним контентом: 5–8 днів. Повне рішення з depth occlusion, кастомним освітленням та підтримкою 200+ пристроїв: 3–5 тижнів. Вартість розраховується індивідуально після аналізу вимог.







