ARKit 与 ARCore:平台 AR 开发实战
ARKit 与 ARCore:平台 AR 开发实战
简介
增强现实(AR)技术已从科幻走入日常应用。苹果的 ARKit 和谷歌的 ARCore 是目前移动 AR 开发的两大主导平台。本教程将带你从零开始,理解两者的核心能力、开发流程、平台差异,并动手实现你的第一个 AR 应用。无论你准备开发 iOS 还是 Android,或者希望跨平台部署,都能获得所需的实战技能。
认识 ARKit 与 ARCore
什么是 ARKit?
ARKit 是苹果为 iOS 设备提供的增强现实框架,首次在 iOS 11 中推出。它利用设备的摄像头、运动传感器和处理器,实现高精度的运动追踪、场景理解以及光照估计。目标是将虚拟物体自然融入现实世界,让它们看起来就像真实存在于空间中一样。
ARKit 的核心功能
- 视觉惯性测量系统(VIO):融合摄像头图像与惯性测量单元(IMU)数据,实现无需外部标记的 6 自由度设备追踪。
- 平面检测:识别水平和垂直平面,为放置虚拟物体提供锚点。
- 光照估计:分析环境光的强度和色温,使虚拟物体呈现与周围环境一致的光照效果。
- 场景重建与深度感知:ARKit 3.5 及以上支持激光雷达(LiDAR)场景几何重建、即时放置物体、人体遮挡以及动作捕捉。
- 人脸追踪:支持前置 TrueDepth 摄像头进行高精度面部网格追踪和表情识别。
什么是 ARCore?
ARCore 是谷歌推出的增强现实平台,用于打造跨 Android 和 Unity 的 AR 体验。它通过软件与硬件的结合,让没有专用深度传感器的 Android 手机也能提供稳定的 AR 效果。
ARCore 的核心功能
- 运动追踪:同样采用 VIO,使用摄像头识别特征点并结合惯性传感器数据确定设备位置和方向。
- 环境理解:检测水平与倾斜表面(如桌子、地面),并在特征点云基础上生成平面。
- 光照估计:提供平均光强度和颜色修正,支持环境光强度调节和球谐函数照明,让渲染更逼真。
- 深度 API:利用单颗 RGB 摄像头生成深度图,实现遮挡、碰撞等真实交互。
- 增强图像与云锚点:可识别 2D 图像并触发内容,还支持多用户共享 AR 体验的云端锚点。
平台对比一览
| 特性 | ARKit | ARCore |
|---|---|---|
| 开发者 | Apple | |
| 支持系统 | iOS 11+ (需 A9 或更新芯片) | Android 7.0+ / 部分 iOS 设备(通过 ARCore 应用) |
| 追踪技术 | VIO + LiDAR (Pro 机型) | VIO + 单目深度 |
| 平面检测 | 水平、垂直、几何形状 | 水平、垂直、任意角度表面 |
| 光照估计 | 色温、强度、环境纹理 | 平均光强、颜色、球谐函数 |
| 人脸追踪 | 前置摄像头,面部网格 | 部分设备支持增强人脸 API |
| 深度与遮挡 | LiDAR 深度 + 手动 API | Depth API (单摄) |
| 跨平台方案 | ARKit 仅官方 iOS | ARCore 可用于 Android 和 iOS (部分功能受限) |
| 云服务与持久化 | Reality Composer, USDZ | 云锚点 (Cloud Anchors) |
选择哪一个很大程度上取决于你的目标用户设备。如果你的受众使用高端 iOS 设备,ARKit 能提供更精确的 LiDAR 体验;如果要覆盖大量 Android 用户,ARCore 是唯一选择。
开发环境搭建
ARKit 环境(iOS)
- 硬件要求:一台运行 macOS 的 Mac,兼容 ARKit 的 iOS 设备(iPhone 6s 以上,推荐使用支持 LiDAR 的 Pro 机型以获得完整功能)。
- 软件要求:
- 安装最新版 Xcode(App Store 下载)。
- 项目部署目标设为 iOS 11.0 以上(AR 功能建议至少设为 iOS 14.0 以使用 RealityKit)。
- 创建项目:
- 打开 Xcode,选择“Augmented Reality App”模板。
- 选择技术实现:推荐使用
RealityKit(现代渲染引擎)或SceneKit(简单 3D 入门);ARKit单独使用时也可以与 Metal 或 SpriteKit 结合。 - 初始代码即会生成一个带有 AR 视图的应用,运行即可看到 3D 物体悬浮在相机画面中。
ARCore 环境(Android)
- 硬件要求:支持 ARCore 的 Android 设备(详细列表见 Google 文档)。Windows、macOS 或 Linux 开发机。
- 软件要求:
- 安装 Android Studio(推荐最新稳定版)。
- Android SDK 平台工具,确保 SDK 级别 24+(Android 7.0)或更高。
- 通过 SDK Manager 安装
Google Play Services for AR(如果设备未预装)。
- 创建项目:
- 在 Android Studio 中选择“Empty Activity”或直接使用 Google 提供的
sceneform-android-sdk(已被 Google 归档,建议使用ARCore SDK for Android搭配自定义渲染引擎如 Filament 或 Unity)。 - 在
build.gradle中添加 ARCore 依赖:implementation 'com.google.ar:core:1.36.0'。 - 在
AndroidManifest.xml中声明 CAMERA 权限,并指定 AR 必需标记(<uses-feature android:name="android.hardware.camera.ar" android:required="true"/>)。
- 在 Android Studio 中选择“Empty Activity”或直接使用 Google 提供的
AR 开发基础概念
在开始编码之前,理解几个共有的核心概念至关重要。
追踪与坐标系
所有 AR 平台都建立一个世界坐标系。当应用启动时,世界坐标原点通常位于设备当前位置。之后,通过视觉和惯性数据更新设备在空间中的变换(位置和朝向)。虚拟内容被放置在相对于世界原点的特定位置,并保持稳定。
- ARKit:使用
ARWorldTrackingConfiguration提供的ARFrame获取相机变换。可见物体置于 ARAnchor 的transform属性定义的 4x4 矩阵空间。 - ARCore:通过
Frame对象获取Camera的视图和投影矩阵。渲染虚拟物体时,需将其模型矩阵与相机视图投影矩阵结合起来。锚点(Anchor)用于确保持久的位置。
平面检测与命中测试
将虚拟物体放在地面或桌面上是 AR 最基础的需求。
- ARKit:使用
ARWorldTrackingConfiguration开启.planeDetection(可设为.horizontal、.vertical或全开)。通过ARHitTestResult实现命中测试,或使用 RealityKit 的ARView.raycast获得更灵活的射线检测。 - ARCore:通过
Session.configure时启用PlaneFindingMode.HORIZONTAL_AND_VERTICAL。使用Frame.hitTest方法传入屏幕触摸坐标,返回命中结果列表,可筛选出满足条件的点。
光照与材质
真实感来源于光照匹配。
- ARKit:
ARFrame.lightEstimate提供环境强度和色温。在 RealityKit 中,默认启用基于图像的光照(IBL),系统会自动估算环境立方体贴图来照亮物体。 - ARCore:
Frame.lightEstimate提供像素强度和色彩校正。最新 API 还支持EnvironmentalHdrLightEstimate,提供方向性光照和球谐系数,用于 PBR 渲染。
动手实战:构建第一个 AR 应用
场景:在水平面上放置一个 3D 虚拟杯子
我们分别用 ARKit 的 SwiftUI + RealityKit 和 ARCore 的 Kotlin + SceneView(使用 OpenGL 或 Filament 渲染)来实现。
使用 ARKit + RealityKit (Swift)
1. 创建 AR 视图
在 ContentView.swift 中引入 ARView 容器:
import SwiftUI
import RealityKit
struct ContentView : View {
var body: some View {
ARViewContainer().edgesIgnoringSafeArea(.all)
}
}
struct ARViewContainer: UIViewRepresentable {
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
// 配置水平面检测
let config = ARWorldTrackingConfiguration()
config.planeDetection = [.horizontal]
arView.session.run(config)
return arView
}
func updateUIView(_ uiView: ARView, context: Context) {}
}
2. 实现命中测试与放置物体
添加点击手势来完成射线检测并放置模型:
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
let config = ARWorldTrackingConfiguration()
config.planeDetection = [.horizontal]
arView.session.run(config)
// 添加点击手势
let tapGesture = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleTap))
arView.addGestureRecognizer(tapGesture)
context.coordinator.arView = arView
return arView
}
class Coordinator: NSObject {
var arView: ARView?
@objc func handleTap(_ recognizer: UITapGestureRecognizer) {
guard let arView = arView else { return }
let location = recognizer.location(in: arView)
// 使用 raycast 代替旧的 hitTest
let results = arView.raycast(from: location, allowing: .estimatedPlane, alignment: .horizontal)
if let firstResult = results.first {
// 加载模型(假设名为 "Cup" 的模型在 Reality Composer 项目中)
let anchor = AnchorEntity(raycastResult: firstResult)
let cupEntity = try! Entity.load(named: "Cup")
anchor.addChild(cupEntity)
arView.scene.addAnchor(anchor)
}
}
}
使用 ARCore + Android (Kotlin)
1. 添加回调与渲染器
ARCore 需要配合 OpenGL 或 Sceneform 等渲染器显示虚拟内容。此处以简化的 HelloArActivity 为例说明逻辑伪代码,具体渲染由框架控制:
class MainActivity : AppCompatActivity(), GLSurfaceView.Renderer {
private lateinit var arSession: Session
private lateinit var arCoreBackgroundRenderer: BackgroundRenderer
// ... 省略 OpenGL 初始化
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arSession = Session(this).apply {
val config = Config(this)
config.planeFindingMode = Config.PlaneFindingMode.HORIZONTAL
configure(config)
}
// 设置触摸监听
surfaceView.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
handleTap(event.x, event.y)
}
true
}
}
private fun handleTap(x: Float, y: Float) {
val frame = arSession.update()
val hits = frame.hitTest(x, y)
for (hit in hits) {
if (hit is PlaneHitResult && hit.hitPointDistance < 0.5f) {
// 创建锚点并放置物体
val anchor = hit.createAnchor()
placeObject(anchor, "models/cup.obj")
break
}
}
}
private fun placeObject(anchor: Anchor, modelPath: String) {
// 在 OpenGL 渲染循环中,使用 anchor 的位姿设置模型矩阵
// 结合虚拟物体节点与 anchor 关联
}
}
平台特色功能深度应用
ARKit 的 LiDAR 增强
支持 LiDAR 的设备(iPad Pro / iPhone Pro)带来显著提升:
- 即时 AR:放置虚拟物体无需预先扫描环境,系统瞬间估算平面。
- 场景重建:
ARMeshAnchor提供环境网格,可用于物理碰撞、遮挡、带影子。 - 人体遮挡:
ARBodyTrackingConfiguration或 RealityKit 中启用peopleOcclusion自动遮挡,虚拟物体可被真人挡住。
示例代码启用人体遮挡:
config.frameSemantics.insert(.personSegmentationWithDepth)
ARCore 的 Cloud Anchors
实现多人共享 AR 体验。一个用户创建一个锚点,将其上传到谷歌云端,并得到一个云锚点 ID。其他用户可以使用此 ID 解析锚点,在同一物理位置看到同样的虚拟内容。
// 上传
val cloudAnchor = session.hostCloudAnchor(anchor)
// 监听完成事件,获取 cloudAnchorId 传递给其他设备
// 解析
session.resolveCloudAnchor(cloudAnchorId)
ARKit 的协同探索(Collaborative Sessions)
ARKit 支持通过 MultipeerConnectivity 框架共享世界地图,实现本地多设备 AR 协作。
session.getCurrentWorldMap { worldMap, error in
// 发送 worldMap 到其他设备
}
// 接收方执行:
session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
session.run(configuration, with: initialWorldMap)
跨平台 AR 开发选择
如果你希望同时支持 iOS 和 Android,可以考虑以下方案:
- Unity AR Foundation:封装了 ARKit 和 ARCore,统一 API,适合 3D 游戏和复杂交互。
- Unreal Engine:同样内置 AR 模板,支持 ARKit/ARCore。
- Vuforia Engine:商业 AR 平台,支持图像识别和跨平台。
- Web AR:使用 WebXR Device API(Chrome 支持 ARCore 底层),通过 8th Wall 等提供更广泛的兼容性。
选择取决于性能要求、团队技能和项目预算。AR Foundation 是个人学习和中小型项目的理想选择。
常见问题与优化
为什么虚拟物体漂移或不稳定?
- 环境光线不足:AR 依赖视觉特征,请确保场景光照充足。
- 纹理单调:白墙、纯色地面缺乏特征点。可增加海报或图案。
- 快速移动:缓慢移动设备以让追踪系统适应。
- 使用优化:ARKit 中调用
session.setWorldOrigin重置追踪状态;ARCore 可调用session.update()频率保持流畅。
性能优化建议
- 限制同时存在的锚点数量。
- 使用低多边形模型和简化纹理。
- ARKit 中使用 RealityKit 的自动 LOD 系统;ARCore 使用 Filament 的渲染优化。
- 注意热管理,长时间 AR 会话会导致设备发热,可适当降低帧率或暂停追踪。
实战项目:AR 家具摆放 App
结合所学,设计一个能检测地面、选择家具模型,并通过触摸在环境中自由摆放的 App。整合以下步骤:
- 环境感知:显示平面可视化(半透明网格/指示器)。
- 模型加载:从本地或网络加载 USDZ(iOS)或 glTF(Android)模型。
- 交互:拖拽旋转、缩放、删除。
- 光照适配:确保模型反映真实光照。
- 拍照分享:捕捉 AR 视图快照。
对于 Android,可借助 Google 的 Filament 和 ARCore Depth API 增加遮挡效果;iOS 可利用 Reality Composer 制作交互式的 AR 场景。
总结与未来方向
ARKit 与 ARCore 不断进化,陆续加入深度感知、语义分割、地理定位 AR 等功能。掌握基础的运动追踪、平面检测和光照估计,是进入 AR 开发世界的钥匙。在实际项目中,根据设备特性选择最合适的 API,并关注官方文档更新。下一步,可以探索 AR 眼镜开发、基于 AI 的实时场景理解,以及 AR 与云服务的融合。
现在,从搭建第一个 AR 场景开始你的练习吧!