大多数浏览器和
Developer App 均支持流媒体播放。
-
探索适用于 visionOS 的对象追踪
探索如何使用对象追踪功能,在 visionOS App 中将现实世界的对象转化为虚拟锚点。了解如何使用对象追踪功能从头到尾打造空间体验。探索如何利用 Create ML 中的机器学习功能创建参考对象,并将相对于目标对象的内容附加到 Reality Composer Pro、RealityKit 或 ARKit API 中。
章节
- 0:00 - Introduction
- 5:07 - Create reference object
- 9:28 - Anchor virtual content
资源
- Exploring object tracking with ARKit
- Forum: Spatial Computing
- Implementing object tracking in your visionOS app
相关视频
WWDC24
WWDC23
-
下载
大家好 欢迎观看“探索 适用于 visionOS 的对象追踪”讲座 我叫 Henning 是一名工程师 来自 Object Tracking 团队 今天 我将向你介绍如何 使用我们新的对象追踪技术 将现实世界的物体转化为虚拟锚点 通过你的 visionOS App 栩栩如生地呈现出来 你可能已经使用 Reality Composer Pro 或 RealityKit 和 ARKit 框架 创建了空间体验 你可能也熟悉在用户的周围环境中 锚定虚拟物体的概念 例如 visionOS App 可以使用我们的 RealityKit 和 ARKit API 相对于平面、图像或手部来放置内容 锚点是提供沉浸式体验的绝佳起点 它模糊了现实世界 与虚拟世界之间的界限 对于对象追踪 我们现在支持 使用现实世界中的物体 作为 App 中的锚点 想象一下 你只需扫一眼日常物品 就会显示相应实用信息 家用电器和设备随附虚拟手册 随时可供查看 收藏品和玩具栩栩如生地呈现在眼前 带你进入一段沉浸式的叙事体验 听起来是不是很神奇? 我来给你展示一下! 这是我的空间视图 桌子上摆放着一些物品 有一个地球仪、一台显微镜 还有一台示波器 利用对象追踪 我的 App 可以通过坐标系和边界框 获取每件物品的位置和方向 如这个示例中所见 既然我的 App 已经知道 我的物体在空间坐标中的确切位置 我就可以更进一步 为它们添加有趣的内容 这还是我的地球仪视图 但这一次 地球仪上方 附加了一个虚拟标签 提示我轻点地球仪可获取更多信息 轻点之后 出现了一些 绕地球仪运转的物体 哇 航天飞机飞进我的房间了! 注意虚拟月球和空间站 是如何在真实的地球仪后面消失的 我喜欢这样的设计 因为它让体验更加身临其境 不过 还有更精彩的 当我再次轻点地球仪时 可以看到地球仪上面 显示了地球的内核 哇 看起来太棒了
这只是我用一件物品创建的一个示例 我相信你也拥有自己的物品 可以让它变得栩栩如生 我们来看看如何使用 对象追踪功能实现这一点
你可以在 App 中非常轻松地 使用对象追踪功能 只需遵循 3 个步骤 首先 你需要提供 3D 模型 来表示你要追踪的现实世界物体 如果你还没有 3D 模型 可以使用一些简单易用的工具 构建一个 然后 你将使用 3D 模型 来训练对象追踪所需的 机器学习模型 在训练时 需要将这个 3D 素材 导入“Create ML”App 中 训练完成后会生成一个参考对象 这是我们今年为对象追踪 推出的新的文件类型
最后 你需要在 App 中 使用这个参考对象 来锚定你的虚拟内容 并打造相应的体验 你可以使用多种工具和框架 来完成这最后一步 我将在这个讲座的后面部分 介绍一些示例 我们先来讨论一下 对象追踪所需的 3D 模型
我之前提到 “Create ML”App 需要 3D 素材来为你的物体 训练机器学习模型 为此 你的 3D 素材需要 采用 USDZ 文件格式 为了确保最佳追踪质量 素材应尽可能像照片一样逼真 基本上 你需要为现实世界物体 准备一个数字克隆版模型 要获得逼真的 3D 模型 一种简单的方法是使用 我们的物体捕捉技术 只需使用一台 iPhone 或 iPad 即可操作 对于包含光面或透明部分的物体 你还可以提供通过 任何其他采集工作流程 生成的多材质素材 如果你有兴趣进一步了解 关于物体捕捉的 详细信息和最佳实践 请观看我们的“认识 iOS 上的 Object Capture”讲座
下面我们来看看对象追踪 支持哪些物体 这项功能最适合用于 周围环境中基本静止的物体 它也支持具有刚性形状和纹理的物体 最后 应该选择非对称物体 这意味着从各种视角看物体 都能看到不同的外观 我刚才展示了我的地球仪 它的追踪效果很好 因为这个球形物体上 具有非对称纹理 在捕获地球仪时 我取下了它的支架 确保在设置追踪时 只考虑物体的刚性部分
下面我们来深入了解一下 如何对你的物体和内容 进行对象追踪 我已经介绍了一些基础知识 但我将在接下来的部分 讨论更多详细信息 首先我将向你展示如何创建参考对象 然后我会通过一个示例 展示如何使用我们的现有工具 将虚拟内容锚定到现实世界物品 我们先来看看如何创建参考对象 我之前提到 对象追踪功能需要针对 每个目标对象单独进行 机器学习训练 我们在“Create ML”App 中集成了 这项训练功能 供你轻松使用 它非常适合完成这项任务 所有机器学习训练 都将在你的 Mac 上本地运行
启动“Create ML”App 后 可以从各种模板中进行选择 例如 Image Classification 或 2D Object Detection 今年我们推出了一项 名为“Spatial”的类别 其中包含我们新的 Object Tracking 模板
训练工作流程包括三个简单的步骤 首先 使用你的 USDZ 素材 配置训练会话 然后 在 Mac 上 本地训练机器学习模型 最后 存储参考对象 以便在 Apple Vision Pro 上 打造你的空间体验 我们来看看之前在讨论中 展示的示例是如何 完成训练的 使用 Object Tracking 模板 创建新项目时 CreateML 会启动训练配置视图 视图中提供一个空的 3D 视口 接下来 只需 将我的 USDZ 文件 从桌面拖移到这个视口中
我在这里使用了之前展示的 地球仪的 3D 素材 3D 视口非常有用 因为我可以从不同的角度 查看 3D 模型 并确认它与现实世界中的物体一致 最好能检查一下右下角显示的尺寸 确认它与物体的实际大小相符
你可以将多个物体 添加到项目以进行追踪 就像我刚才展示的示例一样 只需点按左侧菜单中 模型源旁边的加号图标 即可导入另一个 USDZ 素材 在开始训练模型之前 还需要完成一项配置 那就是为物体选择最合适的视角 这有助于优化对象追踪体验 具体取决于物体的类型以及 它们通常如何放置在你的空间中 例如 许多静止物体 可能只能从竖直位置 或正面位置查看 我可以利用这些信息 来为机器学习训练提供指导 从而实现最佳追踪质量 你可以从三个视角类别中进行选择: All Angles、 Upright 和 Front 我们来详细了解各个类别 你可以在 3D 视口的正下方 找到视角选项 对于我之前添加的地球仪素材 我们来看一下实际物体 可以看到地球仪安装在一个支架上 我可以让它围绕一个 与重力不对齐的轴旋转 由于从任何角度都能查看地球仪 我在配置视图中选择了 “All Angles”选项 使用这个选项时 请记住 从各种角度看 你的物体都应该具有 不同的独特外观 以便实现高质量追踪 这是我的另一件物品 一台显微镜 它应该竖直放置在 与重力对齐的表面上 因此 我选择 “Upright”设置 这个选项不包括底部视角 最后 来看看我的第三件物品 一台示波器 同样 我假设这个物体 将摆放在某个表面上 它同样不需要从背面视角进行追踪 因此我选择“Front”选项 这个模式不包括背面和底部视角 可以让对象追踪功能仅追踪 对我的空间体验重要的内容
请注意 3D 视口 显示了地平面和后平面 以及两条轴分别指向 3D 模型假定的 上方向和前方向 如果你的 3D 模型方向显示错误 比如面朝后显示 你可以在进行训练之前 使用 Reality Composer Pro 更正这个问题 配置现在已经完成 接下来要开始训练了 回到我的项目 只需 点按左上角的“Train”按钮 即可立即开始训练 系统会显示进度条 帮助我了解项目状态 训练一个参考对象 可能需要几个小时 确切时长取决于你的 Mac 配置 另外请注意 只有搭载 Apple 芯片的 Mac 支持这项训练
训练完成后 可以前往“Output”标签 存储生成的参考对象
你可以在 Xcode 的“Developer Tools” 菜单中找到“Create ML”App Create ML 适用于各种任务 除了对象追踪之外 还能训练其他机器模型 如果你有兴趣 进一步了解 Create ML 请观看我们的 “Create ML 的新功能”讲座 现在我们来看看如何 将虚拟内容锚定到参考对象 你可以通过多种方式 利用追踪的对象打造沉浸式体验 你可以使用 Reality Composer Pro 来锚定虚拟内容 也可以使用我们新推出的 RealityKit 和 ARKit API 我想使用 Reality Composer Pro 开始锚定过程 这个工具可以让我以直观的方式 编辑和放置虚拟内容
首先 我使用 visionOS App 模板 新建一个 Xcode 项目
这将自动创建一个默认场景 我可以在 Reality Composer Pro 中 将场景打开 切换到 Reality Composer Pro 我可以找到相同的默认场景 并且可以删除默认球体
在这个场景中 我将首先创建 一个空的 Transform 实体 为它添加 Anchoring 组件
这个实体可充当对象锚点的容器 为了便于进行对象追踪 我们引入了名为“Object”的新目标 我将选择这个目标
接下来 我将导入使用 Create ML 生成的参考对象 并将它与我的 Anchoring 组件相关联
虽然我在这个示例中 使用的是 Reality Composer Pro 但请注意 我也可以 使用 RealityKit API 在运行时创建 Anchoring 组件 回到项目 你会看到视口中出现 原始 USDZ 模型的 一个半透明的视觉提示 如果我需要精确放置 目标对象的特定部分 这个提示就特别有用 我们来探索我的地球仪 体验中使用的场景 我想展示一下 在这个示例中 我如何通过设置场景 来创建其中 一些沉浸式特效
还记得那架直接从地球仪 发射的航天飞机吗? 其实是因为我选择了 一个确切的发射位置 佛罗里达州的卡纳维拉尔角
使用视口中的视觉提示 我可以轻松地在地球仪上 找到这个地点 并设置航天飞机实体 接下来是另一个沉浸式特效 当虚拟月球和空间站 围绕地球仪运转时 我是怎么让它们消失的? 让我们来一探究竟 我针对月球和空间站 使用了时间轴动画 让它们绕地球仪运转 我的场景包含一个单独的 USDZ 地球仪实体 作为子节点 附加到锚点实体 这个地球仪实体将在场景中 作为遮挡形状 由于对象追踪功能 会更新父级锚点实体的变换 因此遮挡物将与实际地球仪对齐 为了完成这个部分 我可以 使用 ShaderGraph 编辑器 在 USDZ 地球仪实体上 应用遮挡材质 这样一来 运转的物体一旦移动到 地球仪实体后面 就会消失
最后 我还使用 Behaviors 组件 给这个遮挡物实体 添加了轻点手势 以便在两个体验之间切换 我们来看看到目前为止 我的构建在 Apple Vision Pro 上的实际效果 我可以轻点播放第一个动画 它将启动绕地球仪运转的物体 我也能看到 它们移动到 地球仪后面就消失了
太棒了 接下来是我的第二个动画 当我再次轻点后 一切按预期运行 很好 但目前我的 App 还没有 通过某种方式告诉我如何开始体验 尤其是如果我刚接触这个体验 我不知道需要探索哪些物体 为了改善这一点 我将在 App 中添加一个辅导 UI 可以显示目标对象的预览 直到对象追踪功能检测到目标对象 我还将添加一个虚拟标签 用于说明如何与我的地球仪交互 RealityKit API 提供内容丰富的工具集 可帮助我 实现这些功能以及更多精彩功能 下面我来说明一下 实现辅导 UI 的步骤 首先 我想显示 一个预览 3D 模型 帮助我在空间中 找到正确的物体 我的辅导 UI 应该响应 锚点状态的变化 所以我需要在代码中检查锚点状态 追踪到对象后 我想展示一个 过渡效果 让显示的 3D 模型 变换到锚点实体的位置 之后 我将添加一个虚拟标签 显示轻点地球仪以开始体验的说明 这个代码示例展示了 如何在辅导 UI 中 显示目标对象的 3D 模型 我借助 ARKit API 从参考对象文件中检索模型 然后载入 USDZ 文件 就像操作任何其他模型实体一样 我还将不透明度设置为 50% 表明这是预览实体 最后 将它添加到 我的场景中进行展示
要了解是否正在追踪对象 首先找到我之前 在 Reality Composer Pro 中 创建的对象锚点实体 然后我可以在更新循环中检查 实体的 isAnchored 旗标状态 并决定在两种情况下 应该显示哪些内容 对于过渡动画 我希望对象预览在追踪开始时向 被追踪对象的位置移动 为此 我需要获取锚点的变换数据 我使用 SpatialTrackingSession 请求正确的授权 然后就可以访问对象锚点的变换 并实现变换动画
最后 我将在地球仪附近 添加一个虚拟标签 说明如何开始这个体验 借助 RealityView 附件 可以 轻松地在 RealityKit 锚点实体上 放置 SwiftUI 元素 首先 我在 RealityView 下的 附件部分中 定义 SwiftUI 元素 然后我可以在场景设置中 找到这个 UI 实体 并将它添加为 之前在 Reality Composer Pro 中 定义的参考变换的子节点 让我们在 Apple Vision Pro 上 查看这些新添加的内容 这一次 在我的地球仪被检测到之前 App 显示了目标对象的预览 告知我需要探索的物体 追踪开始后 这个预览向目标对象移动 引导我的视线随之移动 然后我可以看到一个虚拟标签 说明如何开始体验 非常好 现在是时候总结我的示例了
今年我们还将发布适用于 对象追踪的新 ARKit API 你可以通过它来访问 被追踪对象的边界框 以及相应的 USDZ 文件 正如我们在上一部分中所见 这个 API 可以提供精细的信息 表明何时可以追踪对象 或者是否出现了任何问题 以便你的 App 能够以可控的方式 对这类事件做出响应 除了新的 API 我们还发布了 一款对象追踪示例 App 供你下载并在你的设备上试用 如需了解更多信息 请观看 “使用 ARKit 打造更出色的 空间计算体验”讲座 以上就是探索适用于 visionOS 的 对象追踪的全部内容 对象追踪功能可以解锁 新的空间计算用例 将虚拟内容精确放置在 现实世界中的物品上 我只是展示了利用这项新技术 可以实现的几个示例 还有更多可能性等你探索 Reality Composer Pro 和 RealityKit 提供大量令人惊叹的功能 可供你打造各种出色的空间体验 远不止我今天介绍的这些内容 强烈建议你观看这些讲座 进一步了解相关信息 我和我的整个团队 都非常期待看到你 将奇思妙想化为现实栩栩如生地呈现你的物体
-
-
13:55 - Coaching UI - display object USDZ preview
// Display object USDZ struct ImmersiveView: View { @State var globeAnchor: Entity? = nil var body: some View { RealityView { content in // Load the reference object with ARKit API let refObjURL = Bundle.main.url(forResource: "globe", withExtension: ".referenceobject") let refObject = try? await ReferenceObject(from: refObjURL!) // Load the model entity with USDZ path extracted from reference object let globePreviewEntity = try? await Entity.init(contentsOf: (refObject?.usdzFile)!) // Set opacity to 0.5 and add to scene globePreviewEntity!.components.set(OpacityComponent(opacity: 0.5)) content.add(globePreviewEntity!) } } }
-
14:13 - Coaching UI - check anchor state
// Check anchor state struct ImmersiveView: View { @State var globeAnchor: Entity? = nil var body: some View { RealityView { content in if let scene = try? await Entity(named: "Immersive", in: realityKitContentBundle) { globeAnchor = scene.findEntity(named: "GlobeAnchor") content.add(scene) } let updateSub = content.subscribe(to: SceneEvents.AnchoredStateChanged.self) { event in if let anchor = globeAnchor, event.anchor == anchor { if event.isAnchored { // Object anchor found, trigger transition animation } else { // Object anchor not found, display coaching UI } } } } } }
-
14:31 - Coaching UI - Transform space with SpatialSession
// Transform space struct ImmersiveView: View { @State var globeAnchor: Entity? = nil var body: some View { RealityView { content in // Setup anchor transform space for object and world anchor let trackingSession = SpatialTrackingSession() let config = SpatialTrackingSession.Configuration(tracking: [.object, .world]) if let result = await trackingSession.run(config) { if result.anchor.contains(.object) { // Tracking not authorized, adjust experience accordingly } } // Get tracked object's world transform, identity if tracking not authorized let objectTransform = globeAnchor?.transformMatrix(relativeTo: nil) // Implement animation ... } } }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。