了解 SessionOrigin
SessionOrigin 是 AR Foundation 中引入的一个相对较新的实现,但是这一理念早在几十年前的渲染引擎领域中的相机装置中就已出现。 你可能已经熟悉它的一个名字:MRTK Playspace 节点。 这个概念相当强大,但不幸的是,它没能得到很好的说明,因此人们对其知之甚少。
什么是 SessionOrigin?
SessionOrigin 就是相机附加到的转换对象。 用最简单的话说,通过它可以在虚拟场景中放置相机。 具体点说,就是它定义了一个专门的坐标空间。
与 Unity(以及所有现代渲染引擎)中的转换换父子关系一样,“移动”父级也会“移动”子级。 在此上下文中,术语“移动”的意思是更改父级的全局姿势也将更改子级的全局坐标,当一个对象的全局坐标发生变化时,该对象看起来会像是相对于全局坐标未更改的对象发生了移动。
在这个定义背景下,相机显得相当特殊,因为它没有被渲染。 它确定渲染器的视角。 这里用一个具体示例来说明这一点。
最简单的 SessionOrigin 示例
想象一个非常简单的场景,其中相机在启动时位于原点(与 AR 应用程序中的通常情况一样),在相机前方 10 米处,在 Z 轴上放置一个红色球体(位置 =(0,0,10))。
不管出于什么原因,假设我们希望用户从距离球体 1 米的地方开始。
我们有两个有趣的选择:
- 将照相机移动到新位置 (0,0,9)。
- 将球体移动到新位置 (0,0,1)。
很明显,这两个选项在没有其他上下文的情况下最终是等效的。 在这两种情况下,启动时,球体都在相机前方 1 米处。 唯一的区别是两个对象的绝对全局坐标。 两者的相对坐标,即两者之间的向量,在两种情况中是相同的。
如果使用选项 1,会是什么情况呢? 如果设置了照相机的坐标,跟踪系统将覆盖它们。 但我们不这样做,而是将相机附加到父对象,然后移动父对象。 跟踪器会设置照相机的本地姿势,这会使其相对于父对象移动。 父对象现在就是 SessionOrigin。
为什么要移动相机而不是球体?
在这个简单例子中,这两个选项明显是可互换的。 但请记住,“球体”真实代表了“场景中的一切,但相机除外”。 随着场景的复杂程度的增加,移动任何物体都变得更加复杂。 通过 SessionOrgin 移动照相机始终是完全相同的操作。
此外,还有一些类型的对象很难或不可能重新定位,例如粒子系统或导航网格。 但即使这些都不涉及,更改场景中单个对象的坐标(也即 SessionOrigin)与更改其他所有对象的全局坐标相比,也有明显的优势。
SessionOrigin 不应移动任何内容
再来看看最简单的示例。 但这是一个 AR 应用程序,所以除了渲染的红色球体外,用户还会看到物理环境。 为了简单起见,我们将物理环境限制为一把绿色椅子,如图所示。
现在,当通过 SessionOrigin 移动相机时,就是将其相对于红色球体进行了移动,但显然并没有移动用户,没有将其相对于绿色椅子进行移动。 球体现在看起来距离更近了,但椅子却位于完全相同的位置。
如果椅子上有定位点呢? 定位点应随着红色球体移动,还是相对于座椅保持固定? 整个定位点应相对于物理世界保持固定,因此它显然应与椅子保持在同一位置。
另一个例子是空间网格。 这是为了针对背景、光线投射等提供对应的虚拟版物理环境而生成的网格。我们肯定希望空间网格相对于物理世界保持固定。
更多的例子包括手部网格和眼睛凝视向量。 它们有一个共同的特点,即如果调整(转换)相机的坐标,这些对象的坐标应得到相同的调整。
因此,从概念上讲,所有与相机协调移动的对象也都附加到了 SessionOrgin。 当 SessionOrigin 相对于全局对象(如红色球体)移动时,所有这些对象都会随之移动。
需要强调的是,由于头部跟踪,此移动独立于相机的运动。 跟踪器相对于 SessionOrgin 移动相机。
一个更偏向于数学角度的解释
在 AR 应用程序中,Unity 的全局坐标系默认为任意定位。 除了将重力向量(Y 轴)与“向上”对齐外,位置和方向完全由跟踪器在启动时放置相机时的位置决定。
虽然这对许多应用程序来说没什么影响,但如果能够消除全局坐标空间的任意性,就有的广泛的可能性。
回顾上一个示例,想象一下,按图中所示来设置虚拟红色球体相对于物理椅子的位置,会对应用程序产生很大影响。 可以通过调整 SessionOrigin 来实现这一点。
如果我们希望 (0,0,10) 处的球体与椅子的距离沿 X 轴为 1 米,那么我们希望椅子位于 (-1,0,10)。 当照相机位于原点时,如果我们决定让照相机与椅子的距离沿负 Z 轴为 2 米,那么椅子当前位于 (0,0,2)。 (请记住,物理对象没有固有的坐标,只有由与相机和虚拟对象的邻近程度所暗示的坐标)。
但是,如果我们将 SessionOrigin 转换设置为 (-1,0,8),那么现在相机的位置则是 (-1,0,8)。 正前方 2 米处的椅子位于 (-1,0,10)。 红色球体 (0,0,10) 将显示在椅子右侧 1 米处,与预期一致。
因此,我们有效地使用了 SessionOrgin 转换来重新定位 Unity 的全局空间,以便红色球体和所有其他全局对象恰好出现在相对于物理世界的正确位置。
这种将 Unity 的全局坐标空间与物理世界对齐的简单但强大的机制可用于支持复杂的布局、持久的坐标空间、跨设备共享的坐标空间等。