5月14日公开课:AR/VR开发Q&A问答实录

2021 Qualcomm XR 创新应用挑战赛第七期在线公开课已于5月14日举行。本次公开课面向所有2021 Qualcomm XR挑战赛参赛者公开征集AR/VR相关开发问题,相关问题涉及Unity、Unreal、AR、VR等。

所有征集AR/VR开发问题,都交由受邀的2020 Qualcomm XR挑战赛获奖嘉宾进行解答。参与本次AR/VR开发问答交流的嘉宾有:

  • 薛萌(彼真科技 CTO),2020年获奖作品《命运抉择》
  • 朱稼萌(伊酷网络 CTO),2020年获奖作品《鬼怪猎人》
  • 吕阳鹏(颖视科技 CTO),2020年获奖作品《Dance Maker!》
  • 廖怀富(BeeManStudio CTO),2020年获奖作品《绝地战魂》
  • 严海(仙悦科技 CEO),2020年获奖作品《库贝街》
  • 方桐(上丞科技 CEO),2020年获奖作品《ID家MR新零售系统》
  • 马佳伟(星为棋 CTO),2020年获奖作品《快斩三国》

以下是本次问答的Q&A实录:

问题01:XR开发中有没有比较轻量级的网络框架

薛萌(彼真科技 CTO):网络框架跟XR并没有直接关系,但是建议考虑golang作为后端语言,然后你会发现很多框架库。

方桐(上丞科技 CEO):photon server、super socket。由于Unity已经废弃了uNet,但作为替代我们还可以选用与uNet API几乎相似的Mirror。

马佳伟(星为棋 CTO):可以选用Photon,像糖豆人、HyperDash等游戏都使用了Photon。

严海(仙悦科技 CEO):建议使用开发引擎自带网络框架(有较好的稳定性、兼容性),另外PhotonNetwork也是不错的选择。网络后台的话可以考虑使用Django等比较流行的框架。

廖怀富(BeeManStudio CTO):我尝试来解答一下关于游戏网络通信部分的实现,这里不分vr游戏、ar游戏,还是手机游戏。其基本思路是相通的,就是要找到一种事件模型来处理大规模网络连接的收发事件。针对不同系统平台都有比较明确的处理模型,在windows下就是采用iocp模型,linux下就是选择epoll模型。所谓的重量级和轻量级网络框架,通常是针对框架提供的功能多少和代码量来说。市面上成熟的开源网络框架相关代码库有很多,比如:libevent、 boost.asio、 ace、 poco.Net、等等,这类都是通用网络模型库。但实际应用中,针对不同的产品的特征、不同程序员配置,一般来说很难有找到一个框架既满足产品的特征,又刚好适配项目组的程序员配置。考虑到过来提问题的应该多半是小型研发团队(在程序员不足的情况下又要追求较高的开发效率),下面我针对这一特点给出开发思路,仅供参考:

我们基于客户端使用的是unity,且以c#语言开发为主,服务器端推荐优先顺序如下:

1). 采用.net core技术方案,.net core同时满足跨平台运行、高效网络io模型(底层实现在win下面是iocp,linux下面是epoll)、开发效率、以及与客户端代码的重用性,网络部分的实现比较简单,参考以下2个链接的代码自己整理一下即可,加上而外的一些封装,其网络核心代码基本在1000行左右即可完成:

2). 习惯用c/c++语言的,则选择libevent技术方案,相比.net core方案其开发效率较差,与客户端代码的重用性上基本没有

3). 如果只考虑运行在linux平台下,且希望代码最大化简洁的,则可以考虑从redis中剥离出网络库相关代码,具体可从anet.h、anet.c、ae_epoll.h这三个文件入手

4). 最后从长远来看,是要基于公司/团队技术特点以及对产品线规划等特性,广泛参考市面上成熟开源框架的实现,写一套或者二次封装一套属于自己的网络框架。

问题02:只依靠头显和左右手柄的位置和旋转,如何判定身体的朝向与位置变化?

薛萌(彼真科技 CTO):其实这是一个估计,往深处说有很多细节,比如头部转动到什么程度需要带动身体转动,如何区分移动和身体倾斜,这些细节在Unity的Final IK里都有实现,如果用UE4的话,也可以参考Final IK解决问题的思路。

吕阳鹏(颖视科技 CTO):如果是Unity的话可以参考FinalIK里的VRIK demo

方桐(上丞科技 CEO):将头显启动位置记录为原点,利用三者的传感器与相对位置作为参照物,形成类似空间锚点的定位机制。

马佳伟(星为棋 CTO):一般身体位置都在相机正下方靠后一些的地方。在做朝向时,以头显朝向为主,头显位置到双手连线中点的向量把y置零之后,这个方向可以作为身体朝向的一个修正参数,这样双手做出一些需要侧身动作的时候,VR中的人体也可以较好模拟身体朝向。如果图简单可使用一些现成的插件。

严海(仙悦科技 CEO):身体的位置基本可以通过头显的位置来近似。朝向的话可以利用头部朝向辅助以手柄位置以及场景上下文来综合判断。场景上下文对判断精度有重要影响。仅通过头显和手柄信息判定玩家身体朝向较为困难。

朱稼萌(伊酷网络 CTO):通过获取手柄和头显的数据,不仅可以判断身体的朝向与位置变化,还可以还原部分肩膀,手肘的位置,得出角色IK信息,不同的算法还原度不同,简单的方式可以参考https://www.youtube.com/watch?v=qBooEZnlAA4

问题03:3D物体识别有无好的方法?最好是离线的方案

严海(仙悦科技 CEO):可以考虑使用3D物体在不同视角下的图像来提高物体识别的精确度。另外根据所使用的硬件设备特性,可以考虑使用基于点云或者voxel的物体识别方案。如何提高性能是难点。

方桐(上丞科技 CEO):如Vuforia可以提前上传并下载好3D物体的识别特征数据,打入程序包,可实现离线扫描;或者使用SLAM算法实时扫描物体形成Mesh(比如Kinect,Hololens)

马佳伟(星为棋 CTO):使用HoloLens这种带建模功能的设备是有模型识别解决方案的,也是离线的,例如使用vuforia,提供被识别物体的模型或多角度照片组,就可以识别实际物体。离线方案只是需要提供足够的识别资源库,方便头显识别。

问题04:VR实现局域组网时采用UWB技术实现不延时的可行性

方桐(上丞科技 CEO):UWB技术很难实现不延时毫秒级精度定位,不过可以通过延迟估计算法来优化延时。

问题05:如何避免VR中的穿墙或者穿模?

薛萌(彼真科技 CTO):没法避免,但是可以用防护边界来解决,防护边界设置在墙内侧,接近墙的时候防护边界会优先显示。

严海(仙悦科技 CEO):考虑合理设置场景内模型的物理属性。

方桐(上丞科技 CEO):设定活动区域大小,增加碰撞器。穿墙或者穿模就淡出淡入黑屏并显示出界提示。

吕阳鹏(颖视科技 CTO):当玩家离开规定区域时,一些现有游戏的做法是显示遮罩网格,并且给玩家回到指定位置的强提示

朱稼萌(伊酷网络 CTO):可以使用Unreal现有的解决方案 https://vreue4.com/recent-posts

马佳伟(星为棋 CTO):头部可以增加一个碰撞检测,如果玩家想用头部穿墙,可以将其Rig反向推回去,这样玩家永远用头不可能穿墙。手部追踪的话建议游戏中手是不断向手柄位置移动,如果碰到了物体则停止这种移动,这样玩家虽然手柄在墙内,但是游戏中视觉上的手依旧停在墙外。

问题06:如何设计三维地图中通视情况的分析

方桐(上丞科技 CEO):三维地图面数巨大,需要对模型进行异步加载、使用LOD、剔除、合并网格等方案优化。不要用unity自带的terrian

问题07:在VR驾驶项目中有哪些防眩晕的方案?

薛萌(彼真科技 CTO):保证帧率,避免帧数抖动

方桐(上丞科技 CEO):头显的设备要选好。保持画面高清的同时,帧率大于等于60且能够保持稳定。

吕阳鹏(颖视科技 CTO):google daydream elements有一些locomotion防眩晕的demo可以参考一下。虽然daydream已经停止开发了,但是daydream elements里面有很多不错的VR开发示例

马佳伟(星为棋 CTO):头部追踪使用6DOF,游戏帧数稳定最好在72以上

朱稼萌(伊酷网络 CTO):可以根据速度和角速度变化,改变视角边缘的特效、UI、遮罩大小,实现动态的可视角度和范围变化,来降低晕眩感

问题08:在VR中,有什么真实镜子反射的插件推荐嘛?

严海(仙悦科技 CEO):尝试添加一个面对“自己”的Camera并显示是否可以满足需求。

方桐(上丞科技 CEO):一体机最好利用reflect probe代替反射、折射,多利用贴图;尽量不用实时反射;插件可以使用Amplify Shader Editor

吕阳鹏(颖视科技 CTO):unity assetstore里有很多,例如Fast Mobile Planar Reflection

朱稼萌(伊酷网络 CTO):通用镜子方案一般还是Scene Capture Cube来实现,并通过计算和角色的距离修改替换其Size的大小来做性能优化

问题09:在游戏开发VR一体机运行中 ,如何实现场景实现Bloom那样的后期效果,并且能够不降低性能

薛萌(彼真科技 CTO):实测会严重影响帧数,效果不好。官方文档中都是建议不采用。

严海(仙悦科技 CEO):这个需要具体问题具体分析,没有一个统一的标准答案。如果使用的是Unity引擎的话,可以参考参考手册中Platform development->Mobile Developer Checklist 章节来获得原则上的指导。

方桐(上丞科技 CEO):Bloom的着色器使用后期处理延迟渲染,可以共用模糊函数,减少多次blit;要注意RTT的尺寸。不使用复杂的shader,在相机上少挂后期特效的着色器脚本。后期效果最好要延迟渲染。所有一体机应该按照移动设备(手机)的标准来开发,首先着色器的计算量要小,而且你使用的shader不能是含有PC端的代码,比如DX命令,光线追踪等。在一体机上用HDR等屏幕特效着色器,一定要使用匹配移动端算法的着要注意头显SDK的相机Camera是否兼容相机后处理特效。

吕阳鹏(颖视科技 CTO):如果是用后处理方式实现bloom是一定会影响性能的,没记错的话pico官方是不建议使用任何后处理效果的,也一直是所有移动VR平台的一个尚待解决的难题。但是实际上很多vr一体机项目里还是使用了后处理特效,往往是通过项目的整体优化弥补后处理带来的性能损失。另外尽量使用对移动平台友好的bloom特效,具体可以参考soundstage和tiltbrush这两个开源项目bloom特效的实现,unity插件商店里也有针对移动平台优化的bloom特效。如果是pico的话,需要左右眼睛的camera都挂上后处理特效

马佳伟(星为棋 CTO):尽量使用非实时运算的移动端的相机特效,这种后期处理特效一般是由简单的单色、贴图来复合运算出最终图像结果,而非实时根据成像运算

朱稼萌(伊酷网络 CTO):在Unreal中 Bloom属于后期处理,需开启hdr才能实现,因此损耗不可避免。 可以通过修改渲染管线,或寻找替代方案来实现。部分优化参考链接:https://pan.baidu.com/s/1AYcAty902gkynotyhFK58g 提取码:awa8

问题10:Unity Shader Graph中如何调节自发光强度数值

严海(仙悦科技 CEO):具体得看你的Shader是如何实现的。从原理上讲,你需要的是改变SurfaceOutput中Emission的值来调节物体发光强度。比较方便的做法是将其作为shader的一个输入属性,从而可以在Editor中进行设置。

方桐(上丞科技 CEO):使用Emission Node节点并设置相应的参数

问题11:在非物理行走的第一人称运动游戏中,移动时画面会颤抖重影

方桐(上丞科技 CEO):如果不是程序本身渲染优化的问题,那一般就是头显双眼之间瞳距和自身双眼之间瞳距的不匹配,直接调整头显即可

吕阳鹏(颖视科技 CTO):unity的话cinemachine了解一下?用于相机的平滑移动很好用,VR里也可用。

马佳伟(星为棋 CTO):一般来说都是帧数问题,成像帧与位移结束点不在同一帧上也会导致画面抖动。物理因为更新帧数高,更容易和成像帧成对出现。总结来说就是,在帧数较高的情况下,图像刷新率和移动刷新率一致基本就不会出现抖动情况了。

问题12:能否谈谈VRTK,MRTK,XR INTERACTION TOOLKITS未来发展情况?VRTK是否即将被XR INTERACTION TOOLKIT取代?MRTK是否为重界面操作类应用首选?

严海(仙悦科技 CEO):我们团队目前在项目中使用的是XR Interaction Toolkits。至于该选择哪种ToolKit而言,个人觉得对市场上头显设备的兼容性是首要的考虑因素。

方桐(上丞科技 CEO):MRTK是微软HoloLens的工具包,只是最新的包已经兼容了主流的VR设备;按照跨平台的优越性来看MRTK和XR是首选;至于被取代只与SDK还更不更新有关系,在自身选择上,优先考虑兼容性好,SDK交流圈比较广的那款。

问题13:基于Mirror的多人实时竞技游戏,后台服务器如何选型,能否推荐相关产品。

方桐(上丞科技 CEO):Mirror是uNet废弃后的最佳替代,但同时也是使用Unity的服务器框架,后台性能最好选择CPU和内存要达到现在个人PC端性能的主流配置;显卡可以不考虑,可以使用命令行令服务端不渲染。

问题14:怎样用unity做出灭火效果

方桐(上丞科技 CEO):粒子与着色器混合使用,粒子可以开启粒子碰撞以达到真实模拟。

问题15:unity实时读取加载超过8k的jpg贴图时候会严重卡顿,想问问有没有办法解决?

方桐(上丞科技 CEO):可以在场景Loading的时候预先加载。使用异步加载,同时做好Loading界面。一定不要在主线程加载如此大的贴图。或者将8k的贴图分块,然后也使用多线程异步加载,类似于网页游戏的大地图那种。3D场景还可以使用地形插件,来让每块绘制平滑过渡,类似原神大地图。

吕阳鹏(颖视科技 CTO):其实应当尽量避免在移动vr平台上加载8k纹理无论是动态的还是静态的,目前性能最好的VR一体机单眼分辨率才多少呢?动态加载纹理过程中的确会遇到很多坑,需要具体问题具体分析,最好打开profiler进行调试。

之前项目里用到的一些优化手段:

  • 使用unitywebrequesttexture代替www.texture
  • 避免使用sprite.create,UI里尽量使用rawimage避免sprite转换
  • new texture时使用压缩率低的纹理格式,因为压缩率越高往往耗时较长,但是如果生成的纹理压缩率太低又会占用大量内存和带宽,需要进行权衡。

问题16:unity中设置color space为linear会大幅度降低性能,能否解决?

方桐(上丞科技 CEO):如果linear确实大幅度降低性能,那么建议还是使用Gamma颜色空间,并从模型单独定制一套着色器的渲染管线,来达到仿真linear颜色的效果;同样可以使用Amplify Shader Editor插件。

问题17:vrtk的最简单接入方式

方桐(上丞科技 CEO):导入SDK,学习Demo并仔细看代码加注释。

问题18:是否可以简单分析一下HTML支持VR\AR的情况

严海(仙悦科技 CEO):据我个人所了解的信息,目前HTML支持VR/AR普遍使用的是WebXR协议。当前移动端浏览器不是全部支持该协议,需要看所使用的目标头显。我知道Oculus Quest是支持的。

方桐(上丞科技 CEO):主流是H5+VR的形式,可以用。但毕竟网页的性能天花板有限,所以用HTML开发VR应尽量轻量。

问题19:如何在场景中实现 Realworld(B站有视频 “沉浸式3D地图应用《Realworld》”) 类似的模型剔除效果?

薛萌(彼真科技 CTO):裁切平面(clipping plane)

方桐(上丞科技 CEO):这个使用shader实现的遮罩传送门的特效,在最新MRTK里有类似Demo。Sci Fi Hologram Shader 插件也可以。

朱稼萌(伊酷网络 CTO):应该就是缩放场景整体模型,然后通过材质对中心区域做反剔除,剔除制作可以参考: https://www.youtube.com/watch?v=_YTw-pFuWig结果反向即可

问题20:可以分享一下unity、Unreal模型优化经验吗?

薛萌(彼真科技 CTO):unity和unreal的官方资料中有大量的技术方案,可以根据各自的需要进行参考

方桐(上丞科技 CEO):根据模型种类指定美术规范,限制面数贴图大小等,让美术处理;使用减面插件进行自动化处理;生成并使用LOD来对场景进行优化。

马佳伟(星为棋 CTO):高精度模型制作使用LOD,多使用法线贴图处理细节而非增加模型面数,例如小圆柱其实可以通过一个四棱柱+法线贴图的方式实现,而非真的需要给到这么多面。另外就是多看成熟上线作品的建模细节可以学习到很多巧妙运用优化点。简单来说就是更多的以画代面,使用合适的渲染手段,尽量减少模型面数。

问题21:VR开发想要多人在线推荐什么网络插件或者怎么实现,我也是独自一人去开发的,渲染优化如何去做,打包之后软件在线更新又是怎么做的?

薛萌(彼真科技 CTO):一个人开发的话可以用Photon做转发服务器,热更新unity需要用到脚本语言,ue可以看一下hot patch插件

严海(仙悦科技 CEO):开发多人在线应用可以考虑使用Unity Multiplayer Networking或者PhotonNetwork框架。

方桐(上丞科技 CEO):网络框架photon server、super socket、Mirror都可以;渲染优化要重点关注Game视图的state状态,多用光照烘焙、批处理。在线更新有ab资源,外部资源,lua,ILRuntime等多种方案。

马佳伟(星为棋 CTO):多人在线游戏推荐去找一找集成的插件,我们使用的是Photon解决方案。渲染优化方法有很多,笼统的说,需要从UI、模型、剔除、Shader这几个方面去优化,可以使用Profile、RenderDoc等辅助工具进行查看调优。在线热更方案的话有很多,国内目前比较流行lua热更。

廖怀富(BeeManStudio CTO):游戏在线更新,大致逻辑:

后台部分:

  • 制作更新包,并生成相应的md5和配置文件,上传到指定的资源服务器上
  • 递增服务端的版本号

客户端部分:

  • 版本号对比。客户端每次登录时,下载服务器端的版本号,与本地对比,如果不一致,则提醒进行更新。
  • 客户端根据版本号的差异,通过http的方式下载需要的更新包,并通过计算md5验证包的完整性(注:在服务端配置好每个版本号升级所需要的更新包列表信息,其中包括:更新包的名字、路径、md5等)
  • 将下载下来的更新包释放到指定目录,简单的则是采用覆盖模式,复杂一点的可以考虑重新计算并合并相关的资源包,根据自己的情况来定。
  • 更新客户端的版本号配置,重新回到步骤1,直到本地版本号与服务端一致,则结束更新逻辑,进入真正的游戏。

这是一个游戏更新的大致逻辑,具体的实现是比较复杂的,牵扯的内容有:资源包切分的规划、模块化加载、http下载技术、断点续传、lua脚本的使用、以及加密解密等。

问题22:buildin urp hdrp 渲染管线在移动VR开发时候的选择

薛萌(彼真科技 CTO):URP更专注性能,HDRP更专注画面,如果项目不是对真实画面有绝对追求,推荐URP

方桐(上丞科技 CEO):移动端开发最好不要使用hdrp

问题23:如何基于VR一体机的PBR渲染优化

薛萌(彼真科技 CTO):控制物体的数量,有节制的使用,因为一体机性能有限

方桐(上丞科技 CEO):可以去MRTK工具包里面找找适合的PBR着色器,同时注意Profile的指标。

马佳伟(星为棋 CTO):基于Profile和RenderDoc的性能指标,减少绘制命令数量、面数、调整Shader命令行,另外引擎方面也可以多使用烘焙而非实时运算来实现视觉效果。

问题24:AR/VR开发中如何提高叠加物体定位的精度和稳定性

方桐(上丞科技 CEO):可以在物品身上添加具有特征的识别卡或者二维码,而不是识别物体本身;更复杂的,可以使用HTC的定位器和激光定位基站来进行额外开发

问题25:AR的系统环境如何设置

方桐(上丞科技 CEO):按照手机端的性能要求设置

问题26:请问现有基于AR的渲染算法是如何考虑真实场景的光照

方桐(上丞科技 CEO):整体场景烘焙+局部区域的实时光照+自身小范围动态阴影

问题27:目前性价比最高的AR工具是哪个?可以简述一下流程吗

方桐(上丞科技 CEO):用主流的XR Interaction Toolkit,而不要用冷门的,这样遇到问题SDK圈子大,才好解决

问题28:HoloLens2如何使用mqtt协议,用于物联设备的参数显示?有没有其他的好的接入方式?

方桐(上丞科技 CEO):根据物联的设备来看需求,一般都是用TCP/UDP协议

问题29:HoloLens2如何方便使用二维码做AR开发?类似vuforia那种,但是vuforia是付费的,想要使用免费的二维码实现类似的功能。

方桐(上丞科技 CEO):github开源二维码识别框架——Zxing,二维码条形码都可以。而且支持HL2和IL2CPP

问题30:Hololens2 用手搬动螺旋桨,实现启动飞机发动机的实现方法(要求:1.用手呈握拳状握住螺旋桨,让螺旋桨随着手部移动转圈。2.不能用远距离射线,也不能用捏合手势。3.最好支持双手搬动)

方桐(上丞科技 CEO):先参考Demo,找到其中有一个关节展示的Demo,根据这个给手指上加碰撞器,来改成自己的需求。比如扣扳机的动作

问题31:请问如何将AI的模型比如 onnx 的文件嵌入到头显中,性能如何?

方桐(上丞科技 CEO):首先你要在引擎中有写解析 onnx 格式的SDK,并调查性能消耗。

问题32:如何在头显中自定义手势识别?

方桐(上丞科技 CEO):参照HoloLens手势关节Demo,取到每个关节数据对象,来进行算法上的计算可实现自定义手势。

问题33:请问VR开发中,液体和搅拌液体的交互如何实现的

方桐(上丞科技 CEO):资源商店有手游端可以使用的液体插件

问题34:请问VR开发中,有没有什么方法/工具能帮助找到抓取点?调试太费时间了

方桐(上丞科技 CEO):真机运行时,启动远程Log和断点调试;或者在运行时内置Log控制台。

马佳伟(星为棋 CTO):Application.logMessageReceived可以在真机抓取游戏ConsoleLog。基于此,很多开发者在Unity Store 写了一些Logger插件,让build出的包体能像Editor下一样给出Console信息,这样可以在真机运行时看见大部分的报错、引用等问题。可以试试看LogViewer,这个插件现在导入有些报错稍微调整一下很好用。

问题35:请问VR开发中,如何实现从抽屉中掏出物体的交互

严海(仙悦科技 CEO):我没有理解从抽屉里掏出物体和普通意义上的抓取物体有什么本质上的不同。也许值得注意的地方是需要合理设置抽屉和物体的物理属性,以避免“穿墙”或是“透模”现象的出现?

方桐(上丞科技 CEO):抽屉打开之后才显示物体或者启动物体的碰撞器,避免可穿模直接取物品。

吕阳鹏(颖视科技 CTO):unity里可以参考VR Interaction Framework,或者VRTK的demo,daydream elements里也有相关的场景

马佳伟(星为棋 CTO):抓住物体时不要直接将物体与手柄绑定父子关系,而是在物体表面生成一个Jiont点,该点以物理的形式和手柄绑定,这样可以模拟出更真实的物理动作与碰撞。

朱稼萌(伊酷网络 CTO):可以使用Unreal现有的解决方案https://vreue4.com/recent-posts