本文作者为GeekPlux,博客地址:http://geekplux.com/2018/01/18/augmented-reality-development-tech-in-web-前端.html。注明作者和地址即可转载。增强现实(以下简称AR)浪潮滚滚而来,Web浏览器作为最易接触的人机交互终端,正在大力发展AR技术。很多Web前端工程师也在寻求转行,所以我把自己近六个月的相关研究成果整理成这篇文章。本文力求将当前前端方向的所有AR技术都罗列出来,不赘述(保证文章篇幅不会太长),仅做总结科普(所以链接很多)文章),散乱写了一个多月(拖沓)),欢迎已经从事该领域或研究的道友指正补充。AR可以简单理解为一种将虚拟图像实时叠加在真实场景上,并能进行交互的技术[1]。我个人认为AR比VR更有前景,主要是因为:AR的优势在于将视线中的真实场景变成了背景,将现实世界和数字世界无缝衔接。当然,这种“无缝”现在还没有,但一直在改进。在谈如何在Web前端做AR之前,有必要了解一下AR实现的两种主要方式及其关键技术:AR实现方式及关键技术AR的实现方式主要有两种[2][3]:光学透视(Opticalsee-through)和视频透视(Videosee-through)。目前,市场上的耳机通常使用其中一种或两种方法,而手持设备(手机、平板电脑等)通常使用视频透视。光学透视是将计算机生成的数字图像显示在眼前一层半透明的镜片上,使真实场景和虚拟信息同时呈现在视网膜上。视频透视技术是先将真实场景通过摄像头记录到电脑中,再与虚拟物体融合压缩,统一呈现在用户面前。两者各有优缺点[4]:光学透视下的实景没有经过计算机处理,因此显示更自然直接;delays等,集成了视频透视类型,匹配准确,最终显示效果同步性高,生成的显示结果可以根据用户需求做进一步处理;但实施起来比较困难,失去了部分真实感。目前(2017年底),Web前端要想实现AR,依赖于视频透视技术。此外,计算机视觉技术在AR中起着至关重要的作用。因为实现AR的核心是识别和追踪。首先,相机需要识别基准标记、关键点、光学图像等;然后根据特征检测、边缘检测或其他图像处理方法进行实时跟踪;最后,将虚拟图像叠加在真实场景上。根据2008年的统计结果,近十年著名AR会议ISMAR中关于跟踪技术的论文占比超过20%[3]。WebAR根据上一节的阐述,我们可以得出一个结论:要实现AR,需要在浏览器中进行识别、跟踪和渲染这三个步骤。此外,还可以结合传感器来提供更多交互或让AR渲染更准确,通过网络连接到云端以加速计算或交换更多数据等。如下图所示,这是一个WebAR流程图我自己整理的。WebAR或移动AR在某些方面还是有很大优势的,比如便携性、丰富的传感器、自带网络等,这里不再赘述。WebVR规范首先,WebAR仍然是一项前沿技术。没有标准或成熟的库可供使用,但已经有大公司和一些开发者在积极推广。2017年10月2日,W3C的WebVR组发布了WebVR规范1.1版初稿,2.0版还在修订中。WebVR是一种开放标准,可让您在浏览器中体验VR。我们的目标是让每个人都能更轻松地访问VR,无论您拥有什么设备。-webvr.info为什么这篇文章的标题是WebAR,这里却提到了WebVR?因为WebVR规范中的一些API也适用于WebAR。例如,VRDevicePose可以获取相机位置。这是目前唯一接近WebAR的标准。有了标准,我们只能针对标准化的接口进行开发,从而适配大多数设备。进一步阅读:用于增强现实的WebVR,用于智能手机AR的WebVRAPI扩展。WebARonARKit、WebARonARCoreARKit和ARCore分别是苹果和谷歌出品的移动端ARSDK,它们提供类似的功能:运动追踪、环境感知和光感应。相信很多对AR感兴趣的开发者都对这两款SDK感兴趣。没有陌生人。但两者都是移动端的ARSDK,所以谷歌的AR团队提供了WebARonARKit和WebARonARCore两个库,让开发者可以使用Web技术基于ARKit和ARCore进行开发,实现WebAR。目前这两个库还在实验阶段,想吃螃蟹的小伙伴不妨去试试。实现原理是结合具体系统(iOS和Android)扩展WebVRAPI。GoogleAR团队封装了一个three.ar.js库,提供了一些有用的ARAPI,包括ARView、ARReticle、ARPerspectiveCamera、ARDebug和ARUtils等。AR.js在2017年SIGGRAPH(顶级图形会议)上,AR.js可以可以说是大放异彩。有人做了一个WebAR相关的session,用AR.js来讲解。AR.js是JeromeEtienne开发的WebAR库,可以用十行HTML实现AR,帧率为60FPS。但其实AR.js做的事情很简单。它主要封装了以下几个库:WebRTC。下面会详细讲解,主要是获取视频流。JSAR工具包。ARToolKit可以说是第一个开源的AR框架。它于1999年发布,一直更新到现在。虽然历史悠久,但仍然被广泛使用(官网的风格完全没有历史感)。主要提供识别和跟踪标记的功能,本文附录有补充。Three.js、Babylon.js、A-Frame。这些都是基于WebGL的渲染库,用来渲染AR环境中要显示的东西,下面会展开。从这个角度来看,AR.js就像把所有轮子放在一起的瑞士军刀,简单易用。作者在GitHub和Twitter上很活跃,有任何问题都可以问他。在WebRTC获取视频流的前三节中,我们提到了一个标准和两个正在形成的框架,这是WebAR的最新进展。指望放出标准,黄花菜肯定要凉了,但我们自己动手,丰衣足食。刚才我们说AR首先要被识别,所以需要用到WebRTC技术。WebRTC(WebReal-TimeCommunication,网络实时通信),顾名思义,是一种支持网络浏览器进行实时语音或视频对话的技术。它有一个很重要的API:getUserMedia()可以实时获取摄像头的视频流,这是实现视频透视AR的前提条件(目前iOS11只支持这个API,Android可以很方便的使用)早期的)。有了视频流,我们就可以分析其中的特征点,利用计算机视觉算法对视频流中的事物进行识别和跟踪。这里有两点需要说明:第一,getUserMedia默认获取的是前置摄像头。如果要获取后置摄像头的视频流,需要使用navigator.mediaDevices.enumerateDevices()遍历设备的音视频设备。详见demo;二是用https打开网页访问摄像头。tracking.js,JSFeat,ConvNetJS,deeplearn.js,keras.js识别和跟踪获取视频流后,工作就是识别和跟踪。你可以把视频流看成是一帧一帧的图像,那么处理视频流的过程就可以理解为图像处理的过程。但是这里其实涉及到一个如何传输视频流的问题。一般有两种方式:1.直接在前端处理视频流。前端直接做图片处理,可以用Tracking.js和JSFeat。这两个库类似,都是在前端做计算机视觉,包括提取特征点,人脸识别等,把WebRTC得到的视频流直接传给他们,调用API就可以得到你想要的效果。对于一些成熟的算法,比如人脸识别,可以直接得到识别结果。如果你要识别的物体比较复杂,你也可以自己计算特征点,但这在前端的计算能力可能不够。关于性能问题下面讨论。说到计算机视觉,就不得不提深度学习。毕竟现在很多图像处理算法都被深度学习打败了。ConvNetJS是斯坦福大学开源的一个前端深度学习框架,可以让你在前端完成深度神经网络的训练。deeplearn.js由GoogleBrain团队开发,功能类似于ConvNetJS。现在ConvNetJS好像维护的不多了,deeplearn.js还在频繁更新。有兴趣的同学可以试试。另一个深度学习库keras.js可以让你在浏览器中运行训练好的Keras模型(Kears是知名的深度学习开发框架),并且支持WebGL2。这些框架在首页提供了丰富的demo,很有意思。和他们一起玩可能会激发你的灵感。2、前端将视频流传输给后端,后端处理后返回结果给前端。处理视频流的另一种方法是将其传递给后端进行处理。都是SLAM算法,后端处理返回前端结果。那么如何传输就成了我们前端同学的一道难题。一般有两种方式:将图片信息传给后台。Canvas提供了两个API,一个是toDataURL,可以生成图片的base64字符串;另一个是toBlob,这个方法是异步的,可以把图片转成Blob文件对象,因为是二进制的,所以传给后台比较方便。在具体使用上,后者比前者效率高一点。将像素信息传递给后端。WebGL的readPixels方法可以得到framebuffer中的像素值。除此之外,应该还有其他方法。简而言之,目标是将前端的图像信息传递给后端。传输方式可以是AJAX也可以是WebSocket,视场景而定。本节主要讲识别和跟踪。事实上,除了简单地处理图像和视频流,我们还可以通过移动设备的各种传感器数据,获取更多的距离、深度、光照等信息,让识别和追踪更加准确。A-Frame,Three.js,Babylon.js,Pixi.js,WebGL渲染与交互说完了识别和追踪,终于要说渲染了。A-Frame是Mozilla团队在2015年开源的WebVR框架,但A-Frame团队最近发布的aframe-xr包含了一些WebAR组件。我们在开头也说过,VR和AR的一些实现是重叠的,所以使用A-Frame的各种组件可以让你用很少的代码构建AR所需要的3D立体世界。说到3D,就不得不提WebGL。WebGL是OpenGLES的浏览器端实现,你可以理解为OpenGL的一个子集。使用WebGL,你可以操作前端的每一个像素。稍微懂一点图形学的同学肯定知道它的强大,它可以调用GPU,所以对于涉及到GPU的前端来说是不可或缺的。WebGL虽然强大,但是编写起来极其复杂,学习成本也很高。最著名的前端3D库Three.js对繁琐的WebGLAPI进行了封装和优化,让你在前端使用更具可读性的代码。编写WebGL。Pixi.js和Three.js做的类似,只是只支持2D渲染,不过还是很有用的,如果你只是想用WebGL做复杂的渲染,不涉及3D场景,试试吧。Babylon.js甚至更好。它是一个游戏引擎,同样封装了WebGL,用于前端的高性能渲染。但是,它与Three.js的侧重点不同。如果你对渲染的精细度要求非常高,比如光影等,那你可以考虑babylon.js,毕竟这是前微软员工开发的游戏引擎……这些基于WebGL的渲染方式有如何交互的一个常见问题,比如hover,click的效果是如何实现的。实际上,WebAR中的交互是非常有限的:如果是桌面设备,也就是电脑,交互类似于浏览网页,包括悬停、点击、拖动等;如果是移动设备,也就是手机或者平板,可能会有缩放交互(这里多说一句,其实在移动AR中,应该尽量避免手指交互缩放,而是引导用户通过将设备移近或移远来放大或缩小)。这些实现依赖于RaycastingalgorithmRaycastingmethod。Three.js直接提供了Raycaster类来实现光线投射算法。其实原理很简单,就是把camera(这里的camera不是指手机的camera,而是渲染时的Camera,可以参考Three.js中的Camera)作为视点,它与您在屏幕上触摸的点的坐标相关联。射线,看看这条射线在你的视野中与哪些物体相交。本节主要讲渲染和交互。实际上,在实现AR时,识别跟踪和渲染交互是同时进行的。如何给用户更好更流畅的体验,是WebAR面临的另一大难题。性能性能是许多人关心的问题。目前浏览器的计算能力确实比不上客户端,但是相比之前也有了很大的提升。识别和跟踪本质上是像素级的计算,对计算能力要求很高。因此,基于制造商的AR定位通常比无制造商的更有效。此外,计算机视觉算法的效率对性能也有很大的影响。比如人脸识别目前比其他识别成熟的多,所以人脸识别算法在Web前端运行起来还是比较流畅的。有很多方法可以提高性能。人们一般首先想到的是使用WebGL调用GPU加速,然后才想到使用WebWorker和WebAssembly。前两个我都试过了,将纯计算代码移到WebGL着色器或WebWorker中。虽然都是加速计算,但是适用于不同的场景。着色器可用于加速仅与渲染(重绘)相关的代码。将与渲染无关的代码放入着色器中会导致重复计算。WebWorker适用于预计算或实时性较低的代码,例如布局算法。我在做AR的时候没有用过WebAssembly,也没有尝试过gpu.js这个库。希望有人试过后告诉我有什么效果。另一种变相“提高”性能的方法是使用滤波算法(如卡尔曼滤波)将卡顿降低到更小的水平,从而使用户的视觉体验看起来更流畅。到最后,WebAR的大潮才刚刚开始,还有很多制高点需要攻克,比如光照预估、性能优化等,希望有兴趣的同学可以积极参与其中。而且,Web前端的技术和人口都在飞速发展,充满了无限的可能性,只限于你的想象力。很早之前做了一个人脸识别+AR的小demo,在GitHub上https://github.com/geekplux/AR-AI-VIS-demo,大家可以玩玩,其实就是几行代码。下一篇可能会写一篇Web前端人脸识别相关的文章。我觉得我给自己挖了一个大坑。希望我的拖延症能早日痊愈。附录:AR开发技术参考[2]总结了当时所有的AR开发技术,如下表所示:该表将AR开发工具分为四类,分别列出。其实现在的AR开发大部分都是用Unity完成的,很多第三方的SDK也是先集成到Unity中,再由Unity输出成对应设备需要的格式。据我观察,表格中的Vuforia是目前使用最多的第三方SDK。ARToolKit在web前端和移动端使用较多。它的开源版本是基于Marker的,并且还提供了机器学习的训练方法,可以让你把任意一张图片训练成一个Marker。另外,由于这张表是2015年的,苹果的ARKit和谷歌的ARCore这两个SDK还没有诞生,所以可以归到表的第三行。参考文献[1]AzumaRT.增强现实综述[J].PresenceTeleoperators&VirtualEnvironments,1997,6(4):355-385[2]BillinghurstM,ClarkA,LeeG.增强现实综述[J].FoundationsandTrendsinHuman-ComputerInteraction,2015,8(2-3):73-272[3]ZhouF,DuhBL,BillinghurstM.增强现实跟踪、交互和显示的趋势:ISMAR十年回顾[C]//第七届IEEE/ACM混合现实和增强现实国际研讨会论文集。Washington:IEEEComputerSocietyPress,2008:193-202[4]RollandJP,FuchsH.Opticalversusvideosee-throughhead-mounteddisplaysinmedicalvisualization[M].剑桥:麻省理工学院出版社,2000,9:287-309
