Highlight
ARKit 4 增加了地理位置锚点、LiDAR 场景深度、改进的光线投射和更广设备覆盖的面部追踪,让 AR 内容能绑定真实坐标、读取米级深度并更快完成物体放置。
核心内容
以前做户外 AR,最大的麻烦是坐标。GPS 能告诉 App 大概在哪里,却不能把一个虚拟标牌稳定放在街角某栋楼前。开发者还要处理本地 AR 坐标和地理坐标之间的转换,用户走几步,虚拟内容就可能漂移。
ARKit 4 把这个问题收进框架。开发者给出经纬度和可选海拔,ARGeoTrackingConfiguration 会结合 Apple Maps 的高精度地图数据、摄像头图像和设备运动数据,完成视觉定位。App 获得的是一个全局感知的 AR pose,虚拟内容可以固定在真实世界的位置。
室内 AR 的痛点也很直接。以前要等平面检测稳定,白墙这类缺少特征的表面会让放置过程变慢。ARKit 3.5 先用 LiDAR 带来场景几何,iOS 14 又开放 Depth API。开发者可以拿到每帧的深度图,也可以让 raycasting 自动利用深度或场景网格,把物体更快放到真实表面上。
这场 Session 的主线很清楚:ARKit 4 把 AR 从“房间里的局部坐标”推进到“真实世界里的位置、深度和表面”。位置锚点解决户外共享位置,Depth API 解决真实场景距离,raycasting 解决放置速度,Face Tracking 则把面部 AR 扩展到更多 A12 或更新芯片设备。
详细内容
地理位置锚点:先确认设备和地点
(06:58)位置锚点从 ARGeoTrackingConfiguration 开始。Session 明确要求先检查两件事:设备是否支持 geo tracking,当前位置是否有足够的地图数据用于视觉定位。
// Check device support for geo-tracking
guard ARGeoTrackingConfiguration.isSupported else {
// Geo-tracking not supported on this device
return
}
// Check current location is supported for geo-tracking
ARGeoTrackingConfiguration.checkAvailability { (available, error) in
guard available else {
// Geo-tracking not supported at current location
return
}
// Run ARSession
let arView = ARView()
arView.session.run(ARGeoTrackingConfiguration())
}
关键点:
ARGeoTrackingConfiguration.isSupported先挡住不支持的硬件,Session 提到位置锚点需要 A12 Bionic 或更新芯片以及 GPS。checkAvailability检查当前地点是否有用于定位的 Apple Maps 数据。- 通过检查后,
ARView的 session 才运行ARGeoTrackingConfiguration()。 - ARKit 会在 session 启动时请求相机和位置权限,失败时要把错误解释给用户。
用 ARGeoAnchor 绑定真实经纬度
(08:38)Session 用旧金山 Ferry Building 做示例。开发者创建 CLLocationCoordinate2D,再创建 ARGeoAnchor,最后把 RealityKit 的实体挂到这个锚点上。
// Create coordinates
let coordinate = CLLocationCoordinate2D(latitude: 37.795313, longitude: -122.393792)
// Create Location Anchor
let geoAnchor = ARGeoAnchor(name: "Ferry Building", coordinate: coordinate)
// Add Location Anchor to session
arView.session.add(anchor: geoAnchor)
// Create a RealityKit anchor entity
let geoAnchorEntity = AnchorEntity(anchor: geoAnchor)
// Anchor content under the RealityKit anchor
geoAnchorEntity.addChild(generateSignEntity())
// Add the RealityKit anchor to the scene
arView.scene.addAnchor(geoAnchorEntity)
关键点:
CLLocationCoordinate2D使用至少 6 位小数精度,Session 用它保证内容能准确放到地点上。ARGeoAnchor(name:coordinate:)只传经纬度时,ARKit 会用地图数据推断地面海拔。arView.session.add(anchor:)把地理锚点交给 ARKit 管理。AnchorEntity(anchor:)让 RealityKit 内容跟随这个 ARKit 锚点。generateSignEntity()代表要显示的虚拟标牌,实际 App 可以替换为模型、说明牌或导航提示。
锚点方向固定,内容变换交给渲染层
(10:32)ARGeoAnchor 的坐标轴固定到方位:X 轴指向东,Z 轴指向南,Y 轴向上。锚点本身不可变,旋转和抬高内容要在 RealityKit 实体上完成。
// Create a new entity for our virtual content
let signEntity = generateSignEntity();
// Add the virtual content entity to the Geo Anchor entity
geoAnchorEntity.addChild(signEntity)
// Rotate text to face the city
let orientation = simd_quatf.init(angle: -Float.pi / 3.5, axis: SIMD3<Float>(0, 1, 0))
signEntity.setOrientation(orientation, relativeTo: geoAnchorEntity)
// Elevate text to 35 meters above ground level
let position = SIMD3<Float>(0, 35, 0)
signEntity.setPosition(position, relativeTo: geoAnchorEntity)
关键点:
generateSignEntity()创建要显示的内容实体。geoAnchorEntity.addChild(signEntity)把内容放到地理锚点的局部坐标系里。simd_quatf绕 Y 轴旋转,让文字面向城市方向。setOrientation(_:relativeTo:)以地理锚点为参照设置朝向。SIMD3<Float>(0, 35, 0)把标牌抬高 35 米,适合远距离识别。
用户点击也能生成地理坐标
(14:08)地理坐标不一定来自数据库。用户点击屏幕后,App 可以从 ARKit 世界坐标反查地理位置,再保存为新的位置锚点。
let session = ARSession()
let worldPosition = raycastLocationFromUserTap()
session.getGeoLocation(forPoint: worldPosition) { (location, altitude, error) in
if let error = error {
...
}
let geoAnchor = ARGeoAnchor(coordinate: location, altitude: altitude)
}
关键点:
raycastLocationFromUserTap()表示从用户点击位置得到 AR 世界坐标,Session 提到它可以来自 raycast 或平面上的点。getGeoLocation(forPoint:)把 ARKit 世界点转换成地理位置和海拔。- 回调里的
error要处理,定位失败时不能保存错误锚点。 ARGeoAnchor(coordinate:altitude:)适合保存用户创建的兴趣点。
Depth API:每帧读取米级深度和置信度
(20:32)LiDAR 设备上,ARKit 4 暴露了 sceneDepth frame semantic。启用后,每个 ARFrame 都可以读取 ARDepthData,其中包含 depthMap 和 confidenceMap。
// Enabling the depth API
let session = ARSession()
let configuration = ARWorldTrackingConfiguration()
// Check if configuration and device supports .sceneDepth
if type(of: configuration).supportsFrameSemantics(.sceneDepth) {
// Activate sceneDepth
configuration.frameSemantics = .sceneDepth
}
session.run(configuration)
...
// Accessing depth data
func session(_ session: ARSession, didUpdate frame: ARFrame) {
guard let depthData = frame.sceneDepth else { return }
// Use depth data
}
关键点:
ARWorldTrackingConfiguration()仍然是普通世界追踪的入口。supportsFrameSemantics(.sceneDepth)检查设备是否支持 LiDAR 场景深度。configuration.frameSemantics = .sceneDepth打开深度输出。frame.sceneDepth返回ARDepthData,其中深度像素的单位是米。- Session 提到深度图和相机画面长宽比一致,但分辨率更小。
人物遮挡和深度可以共用
(21:12)如果 App 已经使用 personSegmentationWithDepth,支持 sceneDepth 的设备会自动提供场景深度,Session 说明这不会带来额外功耗。
// Using the depth API alongside person occlusion
let session = ARSession()
let configuration = ARWorldTrackingConfiguration()
// Set required frame semantics
let semantics: ARConfiguration.FrameSemantics = .personSegmentationWithDepth
// Check if configuration and device supports the required semantics
if type(of: configuration).supportsFrameSemantics(semantics) {
// Activate .personSegmentationWithDepth
configuration.frameSemantics = semantics
}
session.run(configuration)
关键点:
personSegmentationWithDepth是人物遮挡所需的 frame semantic。supportsFrameSemantics(semantics)仍然是启用前的设备能力检查。- 开启后,App 可以继续使用人物遮挡,并在支持设备上读取
sceneDepth。 - 这适合把虚拟物体放在人和真实环境之间,增强遮挡关系。
Raycasting:用查询取代旧 hit-testing
(25:41)ARKit 4 推荐用 raycasting 做物体放置。LiDAR 设备上,raycasting 会利用 scene depth 或 scene geometry,在白墙这类缺少特征的表面也能更快给出结果。
let session = ARSession()
hitTest(point, types: [.existingPlaneUsingGeometry,
.estimatedVerticalPlane,
.estimatedHorizontalPlane])
let query = arView.makeRaycastQuery(from: point,
allowing: .estimatedPlane,
alignment: .any)
let raycast = session.trackedRaycast(query) { results in
// result updates
}
关键点:
- 上半段展示旧
hitTest写法,通常还需要开发者自己过滤多个结果。 makeRaycastQuery(from:allowing:alignment:)用一个查询描述射线、目标表面和对齐方式。.estimatedPlane允许 ARKit 根据当前理解估算表面。.any允许水平和垂直等不同方向的表面。trackedRaycast会随着 ARKit 对场景理解更新而持续回调结果。
核心启发
-
做什么:做一个户外地标导览 App,用户走到建筑附近就看到悬浮说明牌。 为什么值得做:位置锚点可以把内容绑定到经纬度,ARKit 负责视觉定位和本地坐标融合。 怎么开始:用
ARGeoTrackingConfiguration.checkAvailability检查地点,再用ARGeoAnchor(name:coordinate:)放置每个地标。 -
做什么:做一个门店或展馆的 AR 路标系统,把入口、服务台和出口标在真实空间中。 为什么值得做:
ARGeoTrackingStatus会告诉你当前处于初始化、定位中还是已定位,适合引导用户举起设备看向建筑。 怎么开始:启动 geo tracking 后持续监听状态,只在 localized 且精度达标时显示导航内容。 -
做什么:做一个 LiDAR 房间扫描预览,把每帧深度转成点云,用颜色显示真实场景。 为什么值得做:
frame.sceneDepth提供 depth map 和 confidence map,Session 的示例正是把深度反投影成 3D 点云。 怎么开始:启用.sceneDepth,在session(_:didUpdate:)里读取ARDepthData,按置信度过滤低质量点。 -
做什么:做一个更可靠的 AR 家具摆放功能,点击白墙或空地也能快速放置。 为什么值得做:ARKit 4 的 raycasting 会在可用时利用 scene depth 或 scene geometry,减少旧 hit-testing 后的自定义筛选。 怎么开始:用
arView.makeRaycastQuery(from:allowing:alignment:)创建查询,再用session.trackedRaycast跟踪放置结果。 -
做什么:做一个面部贴纸或实时表情角色功能,覆盖更多没有 TrueDepth 的设备。 为什么值得做:ARKit 4 把 Face Tracking 扩展到带前置摄像头且使用 A12 Bionic 或更新芯片的设备。 怎么开始:按设备能力检查 Face Tracking,使用 face anchors、face geometry 和 blendshapes 驱动虚拟内容。
关联 Session
- Shop online with AR Quick Look — 把商品模型放进网页和购买流程,适合延伸 AR 内容展示。
- What’s new in RealityKit — 继续了解 ARKit 4 之上的渲染、动画、物理和音频能力。
- What’s new in USD — 学习 AR 内容资产、锚定和交互行为的制作基础。
- Platforms State of the Union — 从平台视角了解 LiDAR、Depth API 和 Scene Geometry 的系统背景。
评论
GitHub Issues · utterances