Highlight
ARKit 在 visionOS 2.0 新增 Room Tracking,把原来只有几何顶点的 mesh 数据升级为带有房间边界语义的 RoomAnchor,让应用可以按房间切换虚拟内容。
核心内容
做 visionOS 应用的开发者都会碰到一个问题:ARKit 给你一堆 mesh 顶点和平面锚点,但你的代码没法判断”用户现在在哪个房间”。你只能靠坐标和几何去猜,猜错了虚拟内容就放错地方。Super Fruit Ninja 之所以能把水果残渣溅到地板上,靠的是 scene understanding,但去年的 API 只能识别平面和 mesh,做不到”房间”级别的语义。
今年 ARKit 加入了 Room Tracking,直接告诉你用户当前所在房间的边界、墙壁和地板几何体,还能在用户从客厅走到卧室时自动切换数据源。同时新增的 Object Tracking 允许你用 USDZ 模型注册一个真实物体,ARKit 持续追踪它的位置和朝向,适合教育、工业这类需要在真实物品上叠加虚拟内容的场景。Plane Detection 也补上了 Slanted 对齐方式,能检测斜面了。此外,World Tracking 在暗光环境下会自动降级为仅朝向追踪,Hand Tracking 则支持了 display-rate 输出和手部预测,降低了交互延迟。
详细内容
Room Tracking
RoomTrackingProvider 是今年新增的 DataProvider,需要 world sensing 授权。它能提供当前房间的 RoomAnchor,以及异步的 anchor 更新序列(03:35)。
// RoomTrackingProvider
@available(visionOS, introduced: 2.0)
public final class RoomTrackingProvider: DataProvider, Sendable {
/// The room which a person is currently in, if any.
public var currentRoomAnchor: RoomAnchor? { get }
/// An async sequence of all anchor updates.
public var anchorUpdates: AnchorUpdateSequence<RoomAnchor> { get }
...
}
关键点:
currentRoomAnchor直接返回当前房间的锚点,为nil时说明 ARKit 没有识别到封闭空间anchorUpdates是异步序列,适合监听房间切换事件- RoomTrackingProvider 只更新当前所在房间的 anchor 数据,不会同时更新所有历史房间
每个 RoomAnchor 包含房间的几何信息(04:20):
@available(visionOS, introduced: 2.0)
public struct RoomAnchor: Anchor, Sendable, Equatable {
/// True if this is the room which a person is currently in.
public var isCurrentRoom: Bool { get }
/// Get the geometry of the mesh in the anchor's coordinate system.
public var geometry: MeshAnchor.Geometry { get }
/// Get disjoint mesh geometries of a given classification.
public func geometries(of classification: MeshAnchor.MeshClassification) ->
[MeshAnchor.Geometry]
/// True if this room contains the given point.
public func contains(_ point: SIMD3<Float>) -> Bool
/// Get the IDs of the plane anchors associated with this room.
public var planeAnchorIDs: [UUID] { get }
/// Get the IDs of the mesh anchors associated with this room.
public var meshAnchorIDs: [UUID] { get }
}
关键点:
isCurrentRoom判断该锚点是否代表用户当前所在房间,用于按房间切换虚拟内容geometry返回的 mesh 比普通 mesh anchor 更贴合房间边界geometries(of:)按分类(墙/地板)返回分离的几何体,适合做遮挡或整面墙的虚拟传送门contains(_:)可以判断一个 3D 点是否在房间内,配合 world tracking 可以实现”走进某房间才触发”的效果planeAnchorIDs和meshAnchorIDs让你可以过滤出属于当前房间的锚点,避免对房间外的数据做昂贵的计算
Object Tracking
Object Tracking 需要先通过 CreateML 生成 ReferenceObject,然后在运行时加载并启动追踪(08:06)。
// Object tracking
Task {
do {
let url = URL(fileURLWithPath: "/path/to/globe.referenceobject")
let referenceObject = try await ReferenceObject(from: url)
let objectTracking = ObjectTrackingProvider(referenceObjects: [referenceObject])
} catch {
// Handle reference object loading error.
}
...
}
关键点:
- ReferenceObject 从文件 URL 加载,也可以从 Bundle 加载
- 一个 ObjectTrackingProvider 可以同时追踪多个 ReferenceObject
- 加载失败会抛异常,需要 catch 处理
启动 session 并监听状态(08:27):
let session = ARKitSession()
Task {
do {
try await session.run([objectTracking])
} catch {
// Handle session run error.
}
for await event in session.events {
switch event {
case .dataProviderStateChanged(_, newState: let newState, _):
if newState == .running {
// Ready to start processing anchor updates.
}
...
}
}
}
关键点:
session.run()是 async 的,需要 await- DataProvider 进入
.running状态后才能处理 anchor 更新 - 通过
session.events异步监听状态变化
追踪结果以 ObjectAnchor 形式返回(08:43):
// ObjectAnchor
@available(visionOS, introduced: 2.0)
public struct ObjectAnchor: TrackableAnchor, Sendable, Equatable {
/// An axis-aligned bounding box.
public struct AxisAlignedBoundingBox: Sendable, Equatable {
...
}
/// The bounding box of this anchor.
public var boundingBox: AxisAlignedBoundingBox { get }
/// The reference object which this anchor corresponds to.
public var referenceObject: ReferenceObject { get }
}
关键点:
boundingBox提供检测到物体的轴对齐包围盒,可以获取 center、extent、最小/最大坐标referenceObject指向匹配的 ReferenceObject,可从中获取原始 USDZ 文件路径- Object Tracking 只能追踪静态放置的物体,不能追踪运动中的物体
World Tracking 光照降级
暗光环境下,ARKit 自动从完整追踪降级为仅朝向追踪。SwiftUI 新增了 worldTrackingLimitations 环境值来通知应用(11:03):
struct WellPreparedView: View {
@Environment(\.worldTrackingLimitations) var worldTrackingLimitations
var body: some View {
...
.onChange(of: worldTrackingLimitations) {
if worldTrackingLimitations.contains(.translation) {
// Rearrange content when anchored positions are unavailable.
}
}
}
}
关键点:
- 当
.translation出现在 limitations 中,说明位置追踪已不可用,只剩朝向追踪 - 可以在此回调中重新排列已放置的虚拟内容,或提示用户移到更亮的环境
- 系统层面已经自动降级为朝向追踪,不会完全丢失追踪
Hand Tracking 预测
HandTrackingProvider 现在以 display rate 输出数据。同时新增手部预测 API,可以在 Compositor Services 渲染场景中提前预测手的位置(12:51):
// Hands prediction
func submitFrame(_ frame: LayerRenderer.Frame) {
...
guard let drawable = frame.queryDrawable() else { return }
// Get the trackable anchor time to target.
let trackableAnchorTime = drawable.frameTiming.trackableAnchorTime
// Convert the timestamp into units of seconds.
let anchorPredictionTime = LayerRenderer.Clock.Instant.epoch.duration(to:
trackableAnchorTime).timeInterval
// Predict hand anchors for the time that provides best content registration.
let (leftHand, rightHand) = handTracking.handAnchors(at: anchorPredictionTime)
...
}
关键点:
trackableAnchorTime是 visionOS 2.0 新增的时间戳,代表最佳内容对齐时刻- 将其转换为秒数后传给
handAnchors(at:),ARKit 会做前向预测 - 预测结果延迟更低,但精度会有所牺牲,适合需要紧密贴合手部的场景
- 如果对精度要求高而对延迟不敏感(如手势检测、绘画),用 display-rate 的异步更新更好
核心启发
-
基于房间的体验切换:用 RoomTrackingProvider 的
isCurrentRoom和contains(_:)为每个房间定制不同的虚拟内容。为什么值得做:用户对”走到不同房间看到不同东西”的体验有直觉期待,这比手动按坐标分区更可靠。怎么开始:在 Full Space 中启用 RoomTrackingProvider,监听 anchorUpdates,切换时替换场景内容。 -
真实物体叠加虚拟信息:用 Object Tracking 在工业设备、教学模型、桌游配件上叠加 3D 标注或动画。为什么值得做:教育、维修、博物馆场景天然需要”对着实物看讲解”的交互,目前 visionOS 上这类应用还很少。怎么开始:用 CreateML 训练 ReferenceObject,放入 ObjectTrackingProvider 运行,用 ObjectAnchor 的 boundingBox 定位叠加位置。
-
暗光环境优雅降级:监听
worldTrackingLimitations,在位置追踪丢失时自动把虚拟内容从锚定模式切换为跟随视角模式。为什么值得做:用户不会总是待在灯光明亮的环境,不做降级处理就会看到内容漂移或消失。怎么开始:在 SwiftUI 视图中.onChange(of: worldTrackingLimitations)检测.translation限制,触发内容重排逻辑。 -
低延迟手部交互:对需要手部紧密贴合的场景(如抓取虚拟物体),使用手部预测 API 而非默认的异步更新。为什么值得做:异步 HandAnchor 有固有延迟,手快的时候虚拟物体会”跟不上手”,预测可以缩小这个差距。怎么开始:在 Compositor Services 渲染循环中用
drawable.frameTiming.trackableAnchorTime获取目标时间,调用handAnchors(at:)获取预测结果。
关联 Session
- Explore object tracking for visionOS — 详解如何用 CreateML 生成 ReferenceObject 并训练物体追踪模型
- Dive deep into volumes and immersive spaces — 深入了解 visionOS 中 Volume 和 Immersive Space 的自定义方式
- Create custom environments for your immersive apps in visionOS — 为沉浸式应用创建自定义环境的视觉与性能最佳实践
- Build a spatial drawing app with RealityKit — 用 RealityKit 实现空间绘画应用,展示 hand tracking 的实际用法
评论
GitHub Issues · utterances