案例研究 - 看透现实中的洞

当人们考量混合现实以及 Microsoft HoloLens 的用途时,通常会扣住这样的问题:“我在房间里可以添加哪些物体?”或“我可以在自己的空间上放置什么?”。我想重点介绍另一个大家可能会考虑到的方面,这本质上是魔术效果,就是使用相同的技术来观察或透视周围的物体。

技术

如果你在 RoboRaid 中与打破墙壁的外星人对战过,在 Fragments 中解锁过墙上的保险箱,或者有幸看过 2015 年 E3 展会上的 Halo 5 体验中的 UNSC Infinity 机库,那么你就知道我在说什么了。 可以根据你的想象,利用此视觉技巧在石膏墙板上打临时的洞,或在松动的地板下隐藏一些秘密天地。

RoboRaid adds three-dimensional pipes and other structure behind your walls, visible only through holes created as the invaders break through.

RoboRaid 在墙后添加了三维管道和其他结构,只能通过入侵者打破墙壁时产生的洞才能看到这些结构。

使用 HoloLens 上的这些独特的全息影像之一,应用可以呈现墙后或穿过地面的内容的视觉效果,看上去就和通过实际窗口呈现的现实效果一样。 向左移动,就能看到右侧的内容。 再靠近一点,就能把这些内容看得更清楚。 主要区别在于你可以穿过真正的洞,但不能穿过坚实的地面去触碰到这种神奇的全息内容。 (我会将任务添加到积压工作 (backlog)。)

幕后

此技巧是两种效果的组合。 首先,全息内容是通过使用“空间定位点”固定到世界上的。使用定位点,可让内容处于“世界锁定”状态,意味着你正查看的内容在视觉上不会偏离它附近的物理对象,即使在你移动或基础空间映射系统更新房间的 3D 模型时也是如此。

其次,全息内容在视觉上仅限于一个非常具体的空间,因此只能通过现实中的洞来查看。 要通过合乎逻辑的洞、窗口或门口来查看内容,这种遮挡是必需的,也很管用。 如果没有东西挡住大部分视场,通往侏罗纪秘密世界的空间裂缝可能看起来就像一只摆放不当的恐龙。

This is not an actual screenshot, but an illustration of how the secret underworld from MR Basics 101 looks on HoloLens. The black enclosure doesn’t show up, but you can see content through a virtual hole. (When looking through an actual device, the floor would seem to disappear even more because your eyes focus at a further distance as if it’s not even there.)

这不是实际的屏幕截图,而是 MR Basics 101 中的秘密地下世界在 HoloLens 上显示效果的图示。 黑色的遮挡没有显示出来,但你可以通过一个虚拟的洞看到内容。 (使用实际设备观察时,地面的存在感会更低,因为你的眼睛聚焦在更远的地方,好像根本就没有地面。)

世界锁定全息内容

在 Unity 中,使全息内容处于世界锁定状态与添加 WorldAnchor 组件一样简单:

myObject.AddComponent<WorldAnchor>();

WorldAnchor 组件会不断调整其 GameObject(以及层次结构中该对象下的任何其他内容)的位置和旋转状况,使其相对于附近的物理对象保持稳定。 请采用此方式创作自己的内容,即让对象的根部轴心点位于这个虚拟洞的中心。 (如果对象的轴心点在墙的深处,则它在位置和旋转上的轻微调整会更明显,并且洞可能看起来不太稳定。)

遮挡除了虚拟洞外的所有内容

可通过多种方式选择性地遮挡你看向墙中隐藏内容时的视场。 最简单的方式是利用 HoloLens 使用叠加显示的原理,这意味着全黑对象是不可见的。 可以在 Unity 中实现这一点,而无需使用任何特殊的着色器或材料技巧,只要创建一个黑色的材料,并将其分配给内容中的一个对象。 如果不想进行 3D 建模,只需使用几个默认的四边形对象,并稍微重叠一下。 此方法存在许多缺点,但是起效最快,而且纵使你怀疑自己以后可能需要进行重构,获取真实度较低的概念证明也很好。

上述“黑盒”方法的一个主要缺点是,拍照效果不好。 虽然通过 HoloLens 显示的效果可能看起来很完美,但截取的任何屏幕截图都将显示一个较大的黑色对象,而不是墙壁或地面的剩余部分。 其原因是物理硬件和屏幕截图合成全息影像和现实的方式是不同的。 让我们稍稍偏题一下,来看一些伪数学观点...

伪数学警报! 这些数字和公式是为了阐明一种观点,而不是什么精确的衡量标准!

通过 HoloLens 看到的内容:

( Reality * darkening_amount ) + Holograms

在屏幕截图和视频中看到的内容:

( Reality * ( 1 - hologram_alpha ) ) + Holograms * hologram_alpha

用文字描述就是:你通过 HoloLens 看到的是变黑的现实画面(比如透过太阳镜)以及应用要显示的任何全息影像的简单组合。 但在你截取屏幕截图时,相机的图像会根据每像素的透明度值与应用的全息影像混合。

解决此问题的一种方法是将“黑盒”材料更改为仅写入深度缓冲区,并与所有其他不透明材料一起分类。 有关这种情况的示例,请查看 GitHub 上 MixedRealityToolkit 中的 WindowOcclusion.shader 文件。 此处复制了相关行:

"RenderType" = "Opaque"
"Queue" = "Geometry"
ColorMask 0

(请注意,“Offset 50, 100”行用于处理不相关的问题,因此不包含此行可能更合理。)

实现这种不可见的遮挡材料,可以让你的应用绘制出一个在显示屏和混合现实屏幕截图中看起来均合理的盒子。 至于其他的好处,你可以利用一些巧思来绘制更少的不可见像素,从而进一步提高该盒的性能,但这可能真的会陷入困境,通常没有必要。

Here is the secret underworld from MR Basics 101 as Unity draws it, except for the outer parts of the occluding box. Note that the pivot for the underworld is at the center of the box, which helps keep the hole as stable as possible relative to your actual floor.

这是 Unity 绘制的 MR Basics 101 中的秘密地下世界,但不包含遮挡盒的外部部分。 请注意,地下世界的轴心点位于盒子的中心,这样可以让洞相对于实际地面尽可能保持稳定。

自制

拥有 HoloLens,想要亲自来试试该效果? 最简单的方法(不需要编码)是安装免费的 3D 查看器应用,然后加载我在 GitHub 上提供下载的 .fbx 文件,就可以查看房间里的花盆模型。 在 HoloLens 加载它,就能看见视觉效果发挥作用。 当你位于模型前面时,只能看到小洞中的内容,其他所有内容都不可见。 从其他方向看模型时,它会完全消失。 使用 3D 查看器的移动、旋转和缩放控件,将虚拟的洞置于你能想到的任何垂直表面上,以此获取一些灵感!

Viewing this model in your Unity editor will show a large black box around the flowerpot. On HoloLens, the box disappears, giving way to a magic window effect.

在 Unity 编辑器中查看此模型时,花盆周围会显示一个大黑盒。 在 HoloLens 上,盒子消失了,取而代之的是魔窗效果。

若要生成使用此技术的应用,请查看混合现实教程中的 MR Basics 101 教程。 第 7 章的结尾是地面发生爆炸,露出了一个隐藏的地下世界(如上图)。 谁说教程一定很无聊?

关于接下来又能在哪些情况应用此想法,下面是一些思路:

  • 想办法让虚拟洞里面的内容可以互动。 让用户能从墙外影响到里面的内容,可以真正提高这种技巧能带来的惊奇感。
  • 想办法透过对象看到已知区域。 例如,如何在咖啡桌上放一个全息洞,然后看到它下面的地面?

关于作者

Picture of Eric Rehmeyer Eric Rehmeyer
高级软件工程师 @Microsoft

另请参阅