詹姆斯·卡梅隆1984年的电影《终结者》引入了我们现在认为理所当然的许多科幻风格。其中最为持久的是热成像平视显示器(HUD),能让观众通过阿诺德斯瓦辛格的T-800角色看到世界。在设计圈里,它是被频繁用于学习借鉴及重制的经典用户界面设计之一。

 

本文将介绍如何使用Unity在HoloLens中重制这样的界面。您还可以将这个界面连接到微软认知服务,以对房间中的对象进行分析,加入面部识别,甚至是一些光学字符识别(OCR),来让这个教程更加有趣。您可以点击【阅读原文】查看本文中所有源代码并下载资源包。

 

重制UI

 

 

第一步要了解的是如何重制T-800热成像HUD显示器。首先在Unity中新建3D项目命名为“Terminator Vision”。新建“main”场景,添加HoloToolkit Unity包到项目中。本教程使用了HoloToolkit-Unity-v1.5.5.0.unitypackage。将该资源包导入Unity场景,在Unity编辑器菜单上依次点击HoloToolkit -> Configure,设置项目目标平台为HoloLens。

 

正确配置好Unity项目和场景后,下面为场景添加一个Canvas对象作为显示文本的界面。在层级视图中选中“main”场景点击右键,在弹出菜单中选择GameObject -> UI -> Canvas添加Canvas,重命名为“HUD”。

 

 

这个HUD还需要一些文本,所以下一步为HUD添加文本。在层级视图中,右键点击HUD对象,在弹出菜单中依次选择UI -> Text添加4个Text对象,分别命名为BottomCenterText、MiddleRightText、MiddleLeftText和MiddleCenterText。添加一些文本让UI风格与《终结者》电影中的UI更匹配,如上图所示的文字内容,MiddleRightText、MiddleLeftText和BottomCenterText的内容分别在HUD的右侧、左侧和下侧居中位置

 

在场景视图中调整HUD周围的文本对象,直到与《终结者》电影的截图大体一致。MiddleCenterText暂时留空,稍后将用于显示调试信息。

 

为文本设置正确的字体和颜色也很重要,HUD中的大部分文字字体可能是Helvetica。默认情况下,Unity在Windows平台默认使用Arial字体,很接近Helvetica。将字体颜色设置为灰白色(236, 236, 236, 255),字体样式为粗体,大小为20。

 

HUD底部显示的“MATCH”字体为Heinlein,这也是电影中使用的字体。也可以使用另一种字体Modern Vision来模拟Heinlein。在Assets文件夹下新建文件夹Fonts,将所有自定义TTF字体文件拖拽到Fonts文件夹中。然后将字体赋给BottomCenterText的Font字段,或单击字体字段旁边的目标符号显示选择界面。此外,将“MATCH”的字体大小增加到32,比HUD中的其他文本稍大一点。

 

 

上图中”MATCH“的右侧显示了一个白色方块。要模拟此正方形,需要在HUD对象下新建一个InputFiled(UI -> Input Field),并将其命名为“Square“。删除默认文字,调整其大小和位置,直到与截图相匹配。

 

固定HUD位置

 

 

默认情况下,画布将被锁定在世界空间。但这里我们希望它可以像《终结者》电影中那样固定在屏幕空间。

 

 

在检视面板选择HUD画布查看其属性,来配置摄像机锁定视图。将画布的Render Mode字段值设为Screen Space - Camera。然后将Main Camera从层级视图拖至画布的Render Camera字段中,作为画布被锁定的相机视图。

 

 

HUD的Plane Distance初始设为1米。这是混合现实应用中HUD与脸部的距离。因为HoloLens是立体的,调整每个眼睛的视野直到视觉舒适。目前HoloLens的焦距是2米,所以平面距离(Plane Distance)至少应该设置为焦距大小。

 

 

为了方便起见,将平面距离(Plane Distance)设置为100。HUD对象上的所有内容将按照视野大小进行自动缩放。

 

请注意,将视觉内容锁定到相机视图的做法被称为“头锁”,通常在混合现实设计中不建议采用,因为可能导致视觉不舒适。相反,推荐做法是使用与玩家一起标记的“身体锁定”来创建混合现实中的HUD和菜单。本教程为了实现与电影一致的效果,暂且忽视该规则。

 

粉红世界

 

 

终结者视图应该是热成像视图,整个场景色调为热情的红色,下面使用着色器来实现该特效。

 

 

着色器可以用于改变图片效果,是一种高度优化的算法。可以添加一个带有红色畸变透明通道的着色器到场景,来创建这里的热视觉着色效果。

 

在虚拟现实应用中,虚拟环境是封闭的,所以可以使用RenderWithShader方法将着色器应用到摄像机上。该方法会将着色器应用到所有可见的游戏对象上。然而,在全息体验中不适用RenderWithShader方法,因为现实中的对象也需要进行畸变

 

 

依次点击Unity编辑器菜单Assets -> Create -> Material新建材质。在着色器字段中,单击下拉菜单,找到HoloToolkit - > Lambertian Configurable Transparent。HoloLens应用首选着色器就是HoloToolkit附带的着色器。Lambertian Configurable Transparent着色器可选择红色,这里设为(200,43,38)。

 

 

为HUD对象新增Plane(3D Object -> Plane)命名为“Thermal”。然后将之前设置的Lambertian着色器拖至“Thermal”对象上。将平面旋转设置为270,并设置缩放为(100,1,100),以填满整个视图。

 

最后,如果不希望红色的着色影响文本,请将各Text对象的Z坐标设为-10。 这会将文本拉至HUD前方一点,所以它不受热视觉效果影响。

 

将项目部署到设备或模拟器,以查看Terminator Vision的效果。

 

让文本动起来

 

 

为了将HUD连接到认知服务(Cognitive Services),首先要策划一种使文本动态化的方式。本节含有大量代码,建议点击【阅读原文】查看代码进行学习。

 

选择HUD对象,然后在检视面板中,单击Add Component -> New Script新建脚本命名为“Hud”。双击Hud.cs在Visual Studio中编辑脚本。在脚本的顶部,创建四个公共变量:InfoPanel、AnalysisPanel、ThreatAssessPanel和DiagnosticPanel。它们将用于保存对项目中的Text对象的引用。

 

查看检视面板中的Hud组件,可以看到四个可以设置的新字段。将HUD文本对象拖到这些字段中,如下图:

 

 

在Start方法中,添加一些默认文本,以检测动态文本是否正常运行。

 

部署和运行Terminator Vision应用程序时,应该在Start函数中指定的新文本替代默认文本。现在设置System.Threading.Timer来确定扫描房间进行分析的频率。Timer类测量时间(以毫秒为单位)。它的第一个参数是回调方法。下面的代码将每30秒钟调用一次Tick方法。Tick方法又将调用AnalyzeScene,AnalyzeScene将使用内置的彩色摄像机(称为可定位摄像头)来拍摄终结者眼前的景象,并将其发送到认知服务进一步分析。

 

Unity访问定位摄像机的方式与访问任意网络摄像机相同。这涉及到创建照片捕捉实例的一系列调用,配置摄像机,拍照并将其保存到设备。在该过程中还可以加入终结者风格的消息,发送到HUD以指示进度。

 

如果成功拍摄并保存了照片,就可以获取该照片,将其序列化为字节数组,并发送到Cognitive Services以检索描述房间的标签数组。最后,处理照片捕捉对象。

  

为了进行REST调用,要使用Unity WWW对象。还需通过Unity协同程序进行调用,以免阻塞调用。 可以通过注册获得免费的订阅密钥来使用Microsoft Cognitive Services API。

 

计算机视觉标记功能是检测照片中对象的一种方法。 它也可以用在像这样的应用程序中进行即时对象识别。

 

 

当调用认知服务返回JSON数据时,可以使用JsonUtility将数据反序列化为名为AnalysisResult的对象。使用JsonUtility时需要注意,它只适用于字段,而不适用于属性。如果对象类有getter和setter,JsonUtility将不会对其进行处理。

 

 

现在运行应用程序,它会每30秒更新一次HUD,并显示关于您房间的信息。

 

 

为了让应用程序更加功能化,还可以添加OCR功能。该服务将挑选它所发现的任何单词,并为终结者更新显示。它还会尝试确定其找到的任何单词的原文,以用于进一步分析。

 

 

总结

 

 

这篇文章讲解了如何利用Unity在HoloLens中重现标志性科幻电影中的炫酷视觉效果。并介绍了如何从Unity调用Microsoft Cognitive Services,以进一步接近电影效果。

 

您可以使用通过OCR找到的文本以及Translator API,调用Cognitive Services将其翻译为另一种语言,进一步扩展Terminator Vision应用的功能。还可以使用Bing Speech API以原始语言和翻译语言两种方式朗读文本。

 

请点击【阅读原文】访问Unity官方中文社区(forum.china.unity3d.com)查看Terminator Vision的源代码。

 

锐亚教育