HoloLens中国版终于于5月底在中国上市,同时国内的技术社区经过一年的成长也有了很大的扩张,越来越多的开发者开始进入了HoloLens开发领域,尝试着使用混合现实(Mixed Reality)技术来构建属于未来的创新应用。
HoloLens于2016年初正式开始发货,笔者有幸能够拿到第一波上市设备,当时大多流入国内的方式还是通过人肉搬运。当时的HoloLens开发在全球范围内都处于起步阶段,可以利用的开发资源只有官方文档等少数内容,然而今天则非常丰富,下面我们来看这一年来的变化。
目前的HoloLens开发方式有两种,分别为使用Unity3D引擎开发,和使用DirectX 11原生开发。Unity3D引擎开发是目前最为推荐的开发方式,具有完善的工具链支持,开发的难度较低,图形化的可视场景编辑器也使得构建全息场景的效率更高.同时,使用C++和DirectX也可以开发HoloLens全息场景,并可用来编写中间件。如果偏爱C#的话,借助SharpDX开源库,C#也可以使用DirectX来进行开发。
HoloLens搭载的系统Windows Holographic更名为Windows Mixed Reality,最新版本功能上更为完善。
Unity3D工具最新版本为2017.1.0f3,与HoloLens的集成度更高,内置了Holographic仿真器,可以在试图编辑器中仿真Spatial Mapping功能,引入最新的Video Player组件,可以使用GPU硬件加速来使得全景视频可以在HoloLens上流畅播放。
图1 空间映射仿真器
Visual Studio最新可用版本为2017,免费的社区版功能仍然可以满足HoloLens开发需求,配合Visual Studio Tools for Unity插件可以很方便进行调试编译。
Vuforia SDK是高通开发的AR识别库,目前最新版本为v6.2.x,对HoloLens已有较好的支持,所以我们可以在Unity项目中使用它实现对图像目标(ImageTarget)和标记(VuMaker)的实时追踪,让应用具有更好的混合现实体验。使用前需要去注册Vuforia订阅,免费版有API调用次数限制,若想使用更多调用,则需要注册付费订阅。
图2 集成Vuforia SDK
HoloToolkit项目从HoloLens发货之初就开始出现,早期提供了一些对核心开发特性的封装,包括Gazure、手势识别、语音识别、空间映像等等。经过一年多的发展,小区开发者们贡献了大量的新代码,功能有了大幅提高。其中后来出现的Spatial Understand组件使得我们可以方便的分析Spatial Mapping的空间表面数据,快速的识别不同空间表面的特性,比如墙壁在哪里,地面在哪里。基于它可以实现像微软官方App那样的高质量的空间映射效果。
图3 空间映射最佳实践
HoloLensCompanionKit项目提供了一系列HoloLens的配套工具,虽然不直接运行在HoloLens上,但却能给用户体验带来极大的补充,目前主要分为Holographic Remoting Host、KinectIPD、MixedRemoteViewCompositor、SpectatorView和Windows Mixed Reality Commander 5个组件。其中,Holographic Remoting Host提供了一个示例UWP项目可以将HoloLens上的视图内容在PC或其他UWP设备上串流显示;KinectIPD可以使用Kinect自动测量并为HoloLens设置用户瞳距,精度为+/-2毫米,适用于多人共享一台HoloLens设备的场景,比如做Demo时。MixedRemoteViewCompositor可以让用户查看HoloLens接近实时的视野内容,基于HoloLens内置的混合捕获功能(Mixed Reality Capture)。SpectatorView提供了一组软硬件方案,使得我们可以搭建一套高分辨率的HoloLens实时混合补货硬件,安装于HoloLens上的外部相机可以提供第三方视角的内容,可以获得更高质量的视频和图片内容。Windows Mixed Reality Commander是一个UWP应用,演示了如何通过Windows Device Portal API在教室或Demo环境下管理多台HoloLens和PC设备,可以实现对设备的有效的控制管理。
图4 HoloLen SpectorView硬件平台
HoloLens with ARToolkit项目是基于著名的ARToolkit项目对HoloLens做了适配,使得HoloLens也可以使用上高效的AR追踪体验,可以追踪的目标包括单个标记(Single Marker)、立方体标记(Cube Marker)和多个标记(Multi Marker),最新版v 0.2在常规渲染模式下可以达到45-60fps,在标记追踪模式下可以达到25-30fps的帧速率,效果相当不错。
图5 HoloLens with ARToolkit
正如我们所知道,HoloLens是一款移动计算设备,在保证续航能力的前提下,意味着HoloLens不会具有特别强劲的计算能力,所以性能优化就变得至关重要了。
对于全息场景而言,我们需要权衡图形复杂度、渲染帧速率、渲染延迟、输入延迟、功耗和电池寿命等内容来确保能提供给客户理想的体验。事实上,有三个关键指标需要我们尽可能的满足:
指标 |
目标 |
帧速率 |
60fps |
功耗 |
一分钟内平均功耗处于HoloLens Device Portal性能工具图标中的橙色和绿色区域。如图9中Power部分 |
内存 |
总提交内存小于900M |
为HoloLen开发应用与开发传统桌面应用是完全不同的,因为用户会在物理世界中移动,所以为了使得全息图像能有逼真的体验,必须快速的刷新用户视图。用户每只眼睛看到的视图是不同的,所以我们必须在能模拟物理法则的情况下,以最低的延迟来刷新用户视野,避免全息图形相对真实世界发生漂移。全息场景的渲染管道和第一人称视角的3D游戏的渲染管道是相似的,60fps对HoloLens也是理想的指标,当应用的帧速率接近或达到60fps时,实时低延迟的渲染会让全息场景会达到最佳的视觉体验,看起来会更接近很真实物体。
在应用开发周期中,60fps的目标是我们应该最先努力达成,只有在满足帧速率后,才应当去考虑功耗的优化。而且当画面的帧速率远低于60fps时,此时测出的功耗会有较大的误差。
性能优化建议:
全息应用和其他图形应用一样,视图的复杂度会严重影响渲染性能,因此为了尽可能达到60fps,我们首先关注的应该是对视图复杂度的优化。对于HoloLens而言,视图复杂度的优化应当关注以下方面:
1)模型面数
场景中的3D模型的面数越多,虽然在视觉效果上会越精细越动人,但也意味着会消耗更多的计算和存储资源,对设备的负担越大。当场景中模型的面数过多时,会导致帧速率大幅降低,用户会明显感到画面出现延迟、卡顿,这对于全息场景而言是致命的。在这种情况下,在保证观看效果的情况下,模型的面数越少越好。从我个人的实践经验来看,整个场景中,总渲染面数应当控制在10-20万以内。
图6 面数较低的模型效果
2)着色器Shader
Shader对于图形渲染是至关重要的组件,在HoloLens上也是我们优化的重点。一般来讲,工具生成的通用shader一般太过复杂,很多内容对HoloLens无用,因此我们可以使用高阶着色器语言(HLSL)来自己编写shader,提高视图的渲染效率。Unity3D自带的shader不被推荐使用,取而代之的是推荐使用HoloToolkit-Unity项目中的经过精简优化的shader。
此外,切换shader渲染不同的全息图像对性能的代价非常大,推荐应当对Draw Call进行排序,使得能顺序渲染具有同一着色器的对象,减少切换shader的次数,提高渲染效率。
图7 HoloToolkit中优化后的Shader
3)纹理
场景中使用的纹理应该尽可能使用bilinear双线性过滤模式,可以保证相对平滑的视图过渡效果,这也是Unity3D默认设置,同时慎用trilinear三线性模式,它会降低渲染速度。同时纹理压缩应当尽可能使用DXT压缩并启用MipMap,实现对显存带宽的优化,优化GPU瓶颈。
虽然HoloLens采用了32位英特尔Atom处理作为主处理器,并且将空间映射数据的处理负载交给HPU,但是对于复杂的全息场景而言,我们仍然需要尽可能的提高CPU的利用效率。
性能优化建议:
1)物理组件
物理组件是全息场景中常用的组件之一,但是如果组件数量过多或计算频率过快,则会导致CPU负载极大,导致场景fps一泻千里。因此,在保证功能的前提下,我们应当减少场景中不必要的物理组件,同时降低代码检测频率,降低对CPU的开销。同时在Unity3D中尽可能不要使用网格碰撞器(Mesh Collider),复杂的网状模型虽然可以做到精确的碰撞检测,但会带来高昂的计算资源开销,对于HoloLens而言性价比太低,应当使用其他网格较为简单的碰撞器为优。
2)脚本质量
事实上,CPU的开销还与我们编写的脚本质量密切相关。除了常规的脚本优化方式外,对于Unity3D项目而言,应当避免场景中出现过多的Update()循环。
如果场景中每个物体都具有Update()方法,这会导致引擎大量频繁调用Update方法,带来额外的CPU开销。最佳实践是,可以使用一个Manager对象统一管理其子物体,并在其Update方法中,统一更新其子物体UI。
3).NET Native
HoloLens项目本质上还是Windows 10 UWP项目,默认设置下,当使用Release模式编译项目时,Visual Studio会使用.NET Native技术,将我们的C#托管代码编译为原生二进制代码,大大提高应用的启动速度和运行速度;使用Debug模式则不会使用.NET Native编译,性能远差于Release模式。因此,最佳实践是确保在Release模式下编译生成App,以获得最佳性能。
图8 Release模式启用.NET Native
4)性能监视工具
进行HoloLens性能优化时可以使用现有性能监视工具来提高优化的效率,下面时可用的性能优化工具:
工具 |
监视维度 |
HoloLens Device Portal性能工具 |
功耗、内存、CPU、GPU和帧速 |
Visual Studio图形调试器 (Visual Studio Graphics Debugger) |
GPU, Shader和图形性能 |
Visual Studio诊断工具 (Visual Studio Diagnostic Tools) |
内存, CPU |
Windows性能分析器 (Windows Performance Analyzer) |
内存, CPU, GPU, 帧速 |
其中HoloLens的设备控制面板站点自带性能工具,可以实时收集HoloLens设备的全部性能数据,同时还暴露了Restful API服务,允许我们调用其API获取json格式的性能数据,用于自定义性能数据分析,十分灵活。
其他工具为Visual Studio自带的性能分析工具,也可以很好帮助我们对应用性能进行评估。
图9 HoloLens Device Portal性能工具
随着HoloLens和Unity3D引擎的集成度越来越高,开发的门槛大幅降低,越来越多的开发者可以享受到混合现实技术的乐趣,开发出奇幻的全息场景。与此同时,对于应用性能优化的渴求也越来越高,传统的对CPU、GPU和内存优化技巧仍然可以发挥巨大的作用,而针对平台的最佳实践也可以大幅提高应用的表现,两者共同使用,才能得到最好的性能体验。