使用 Anchor Entity 在 visionOS 中锚定现实世界对象
为何需要 Anchor Entity
在 RealityKit 中,可以使用 Entity 和 RealityView 来加载和渲染 3D 对象,并为他们添加动画,从而创建虚拟现实体验,你可以参考下面的文章了解如何实现。
但是,如果你想将虚拟内容添加到周围的环境,来创建更加具有吸引力的增强现实(AR)体验,这种做法就会有一些限制。想象一下这些应用场景:
家具购物应用
假设你要开发一个家具购物的 AR 应用,该应用允许用户在自己的客厅里虚拟放置沙发来预览效果。如果沙发的虚拟图像不能准确锚定到地面,那么当你移动手机或头部时,沙发可能会看起来漂浮在空中或部分埋入地下,这会破坏真实感和购买决策过程。
历史遗迹增强导览
在历史遗迹的增强现实导览中,游客通过 AR 眼镜看到古代建筑的复原状态。如果这些复原图像不能准确地锚定在真实的遗迹位置上,可能导致虚拟内容与实际遗迹错位,影响教育效果和用户体验。
FSP 游戏场景
类似下面这样的 FPS 游戏场景,需要保持在观察者的前方
AnchorEntity 的引入是为了解决上述这些挑战,确保虚拟对象可以准确、稳定地固定在现实世界的具体位置上。
Anchor Entity 基本概念
什么是 Anchor Entity
AnchorEntity 是 RealityKit 框架中的一个核心概念,用于在 AR 体验中将虚拟内容锚定到现实世界的特定物理位置。通过使用 AnchorEntity,开发者可以定义一个虚拟对象应该出现的精确位置和方向,确保当设备移动或环境变化时,虚拟内容仍然正确地放置和定向。这种锚定使得虚拟内容能够与现实世界的物理元素(如墙面、桌面等)无缝融合。
与 Entity 有什么异同
在 RealityKit 中,AnchorEntity 是 Entity 的一个子类,它专门用于在 AR 环境中创建稳定的参考点。普通的 Entity 可以表示场景中的任何对象,不一定与现实世界的位置关联。
相反,AnchorEntity 通过与现实世界的特定物理特征(如平面、图像标记等)相关联,为其他 Entity 提供了一个稳定的基准。这意味着 AnchorEntity 通常是场景中位置固定的实体,而其他非锚定的 Entity 可以更自由地在虚拟环境中移动或变化。
与 ARAnchor 的异同
ARKit 中的 ARAnchor 和 RealityKit 中的 AnchorEntity ,都是为了将三维模型与现实世界中的对象绑定在一起。AnchorEntity 晚于 ARAnchor 推出,他们之间最重要的区别在于—— AnchorEntity 使用更加简单。
使用 ARAnchor 需要手动配置 Session 会话,并通过代理方法处理更新,而创建 AnchorEntities 不需要手动管理会话,更为自动化,你可以基于特定标准(如平面或图像)定义一个AnchorEntity,RealityKit 会作为其场景管理的一部分处理放置和更新。
使用 AnchorEntity
基本用法
下面这个代码为垂直平面创建了锚点:
let wallAnchor = AnchorEntity(.plane(.vertical, classification: .wall, minimumBounds: SIMD2<Float>(0.6, 0.6)))
.plane
表示创建的锚点类型是平面。其他类型可在【锚点类型】中查看。.vertical
表示锚点应该附着到垂直平面,通常是墙面。.classification
这个参数进一步细化锚点的类型。.wall 表示这个锚点专门用于墙面。这是 RealityKit 用于提高锚点定位精度和相关性的分类。.minimumBounds
这是一个 SIMD2<Float> 类型,定义了锚点有效依附的最小平面尺寸,这里设置为至少 0.6 米 x 0.6 米。这个参数确保 AR 系统只在检测到足够大的平面时才创建锚点,有助于提高应用的稳定性和实用性。
然后使用 Entity 加载一个 3D 模型,并将这个 Entity 作为 wallAnchor
的 Child:
var body: some View {
RealityView { content in
let wallAnchor = AnchorEntity(
.plane(
.vertical, classification: .wall,
minimumBounds: SIMD2<Float>(0.6, 0.6)))
if let entity = try? await Entity(
named: "Shahed-131_special_edition_white")
{
wallAnchor.addChild(entity)
content.add(wallAnchor)
}
}
}
这样我们就实现了将 3D 模型“贴”到墙上的效果:
锚点类型
AnchorEntity 支持多种锚点,目前支持以下几种锚点类型:
注意:RealityKit 在不同的平台支持的锚点类型会有一些区别,以上列表仅表示在 visionOS 中支持的锚点类型,通常 iOS 平台会更多,而 macOS 平台则会更少。
由于支持的锚点类型是持续更新的,你可以查看这个官方文档,获取最完整的类型列表:
Classification 可选类型
classification 参数主要与 .plane 类型的 AnchorEntity 一起使用,用于指定锚点依附的具体平面类型。通过预先指定正确的平面类型,可以提升锚定精度。
目前支持的几种平面分类:
.wall
:表示锚点应该依附到垂直的墙面上。.floor
:用于指定锚点依附到地面。.ceiling
:表示锚点依附到天花板。.table
:指定锚点依附到表面,如餐桌或办公桌。.seat
:适用于锚定到座位,比如椅子或沙发等。.any
:不具体指定平面类型,允许锚点依附到任何检测到的平面。
.plane
类型的锚点。由于分类类型也在持续更新,你可以访问 Apple 官方文档获取最新平面类型列表:
锚定到指定平面(示例)
在之前的示例中,我们已经学会如何将一个 3D 模型锚定到目标平面。这个部分我们来实现,将一张图片锚定到平面(例如墙上),例如下面这样: