AR 能够简单的理解为一种实时将虚拟图像叠加在现实场景中的技术,且能交互,优点在于把目之所及的现实场景变成了背景,并将现实世界和数字世界无缝链接。html
AR 实现的方式和关键技术前端
AR 的主要实现方式有 2 种:光学透视式 (Optical see-through) 和视频透视式 (Video see-through)node
光学透视式是将电脑生成的数字图像显示在眼前的一层半透明镜片上,这样就可使现实场景和虚拟信息同时出如今视网膜上。git
视频透视式技术是将现实场景首先经过相机录入电脑,通过和虚拟对象整合、压缩,再统一呈如今用户眼前。github
目前(2018 年末) Web 前端要想实现 AR,都是靠的视频透视式技术。web
计算机视觉技术在 AR 中起着相当重要的做用。由于实现 AR 最核心的是识别与追踪。首先,相机要先识别基准标志、关键点、光学图片等;而后再根据特征检测、边缘检测或其余图像处理方法来实时追踪;最后将虚拟图像叠加到真实场景中。算法
结合传感器来提供更多的交互或让 AR 渲染得更准确、经过网络链接云端来加速计算或交换更多数据等。npm
由上得出结论:要实现 AR 须要识别、追踪和渲染三步。后端
目前没有标准也没有成熟的库供使用,只有一些规范。api
WebARonARKit, WebARonARCore ARKit 和 ARCore 分别是苹果和谷歌两大巨头出品的移动 AR SDK,提供的功能也相似:运动追踪、环境感知和光线感应但这两个都是移动 AR 的 SDK,因而谷歌的 AR 团队提供了 WebARonARKit 和 WebARonARCore 两个库,以便开发者能用 Web 技术来基于 ARKit 和 ARCore 开发,从而实现 WebAR。目前这两个库都还在试验阶段,想吃螃蟹的人赶忙去试试。其实现原理都是结合特定系统(iOS 和 Android)扩展了 WebVR API。Google AR 团队封装了一个 three.ar.js 的库,提供了一些实用的 AR API,包括 ARView, ARReticle, ARPerspectiveCamera, ARDebug 和 ARUtils 等。
AR.js
AR.js 是 Jerome Etienne 开发的一款 Web AR 库,能够用十行 HTML 就实现 AR,并有 60 FPS 的帧率。它主要封装了如下几个库:
由此观之,AR.js 像是一个把全部轮子都拼起来的瑞士军刀
React 360
EasyAR
AR 首先要识别,那就要用到 WebRTC 技术。
WebRTC(Web 实时通讯,Web Real-Time Communication),顾名思义是一个支持网页浏览器进行实时语音对话或视频对话的技术。经过WebRTC,能够经过网页呼起用户的摄像头,而且实时获取用户摄像头的图像数据的。
它其中有个很重要的 API:getUserMedia() 能够实时获取摄像头的视频流,这是视频透视式的 AR 实现的前提(目前 iOS 11 刚刚支持这个 API,Android 是很早就能用)。
getUserMedia 默认获取的是前置摄像头,若是想获取后置摄像头的视频流,须要用 navigator.mediaDevices.enumerateDevices() 将设备的音频、视频设备遍历获得
要用 https 打开网页才能访问摄像头。
有了视频流咱们就能够分析其中的特征点,运用计算机视觉的算法识别和追踪视频流中的事物。
获取到视频流以后的工做就是识别和追踪了。
视频流你能够看做是一帧一帧的图像,因此处理视频流的过程能够理解为图像处理的过程。但这里其实还涉及到一个如何传输视频流的问题,通常有两种方式:
前端传输视频流给后端,后端处理完毕返回结果到前端
在前端直接处理视频流:
在前端直接进行图像处理,能够用 Tracking.js 和 JSFeat。这两个库相似,都是在前端作计算机视觉的,包括提取特征点、人脸识别等。把 WebRTC 拿到的视频流直接传给它们并调用 API 就能获得本身想要的效果。对于一些成熟的算法,如人脸识别,能够直接拿到识别结果,若是本身要识别的物体比较复杂你也能够本身进行特征点的计算,但这可能在前端会算力不足。
提到计算机视觉,不得不提深度学习,毕竟如今不少图像处理算法被深度学习吊打。ConvNetJS,是斯坦福大学开源的一个前端深度学习框架,可让你在前端完成深度神经网络的训练。deeplearn.js 则是 Google Brain 团队搞的,功能和 ConvNetJS 相似。如今 ConvNetJS 好像不怎么维护了,deeplearn.js 还在频繁更新中,感兴趣的同窗能够试用一下。另一个紧锣密鼓开发的深度学习库 keras.js则是让你能够在浏览器中运行已经训练好的 Keras 模型(Kears 是著名的深度学习开发框架),并支持 WebGL 2。
除了单纯的对图像、视频流处理,咱们还能经过移动端设备的各类传感器数据获取到更多的距离、深度、光照等信息,从而使识别追踪更准确。
识别和追踪以后,接下来是渲染。
渲染出3D场景后,如何交互?
这些基于 WebGL 的渲染方法,有一个共性的难题是如何交互,好比 hover, click 效果如何实现。这些实现起来要依赖于 光线投射算法 Ray casting 方法。Three.js 直接提供了 Raycaster 类供实现 ray casting 算法。摄像头(这里的摄像头不是指手机的摄像头,而是你渲染时的 Camera,能够参考 Three.js 中的 Camera)视做视点,与你在屏幕上触碰的点坐标连城一条射线,看这条射线与你视图中哪些物体相交。
事实上在实现 AR 的时候,识别追踪和渲染交互是同时进行的,如何给用户更好、更流畅的体验是如今 Web AR 的又一大难题。
目前浏览器的算力确实还不足以与客户端去媲美,识别和追踪本质上是像素级的计算,对算力的要求都很高,所以 maker-based 的 AR 定位效率一般比 makerless 的要高不少。此外,计算机视觉算法的效率对性能影响也很大。
目前,在web端,不管采用哪一种实现手段,最主要是运行环境对webRTC、webGL 两个特性的支持程度。
测试发现IOS 12如下不支持、IOS版微信QQ不支持、Safari支持;安卓支持良好。
采用: AR.js Efficient Augmented Reality for the Web
AFrame.js A web framework for building virtual reality experiences
AFrame-ar.js Augmented reality for a-frame.
AFrame-extras.min.js Add-ons and helpers for A-Frame VR.
注意:这种技术方案的特性是基于标记图Maker,也就是说须要一张特定的训练出的标记图才能渲染出AR效果,
因为识别图须要训练,且有特定要求,因此识别图的外观和识别率有关系,识别率低则会致使模型抖动剧烈。
可使用设备打开 官网demo 而后对准 识别图便可体验,或本地运行项目来访问。
下载项目
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
复制代码
安装http-server服务(须要nodejs)
npm install -g http-server
复制代码
使用git bash 工具或其余(除Windows CMD)进入到须要预览的页面,生成SSL证书并经过HTTPS访问
首先进入项目
cd AR.js
复制代码
生成SSL证书
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
复制代码
启动HTTPS服务,经过127.0.0.1 或IP访问
http-server -S -C cert.pem -o
复制代码
例如 https://192.168.3.52:8080/three.js/examples/dev.html 能够看到这里打开了一个dev页面,PC端缺失摄像头而报错。若是你是微信打开,则报错webRTC不支持,可用Safari访问。
使用你的手机打开该页面,扫描特定的识别图,便可感觉webAR的强大。这里也体现了该框架的特性:基于maker图片
这里打开的是使用three.js写法的demo,渲染出了一个立方体并带有动效。
**而在AR.js中分为两种写法:使用three.js结合一堆js库来实现、使用AFrame.js**
在该项目中的example对比发现,使用 three.js 来构建3D场景后,还须要结合 artoolkit.js、threex.js等,<u>学习成本很是高。</u>
使用 AFrame.js 写法时,代码量减小不少,但也须要了解 AFrame.js 、AFrame-ar.js 、AFrame-extras.min.js
复制代码
AFrame.js是火狐的项目,它包含了three.js
AFrame-ar.js能够在web页面上渲染3d
在参考AR.js官网给出的“10行代码实现AR效果”的例子时发现,该demo引用的aframe的版本较旧,而引用官网最新的版本时,所呈现的demo效果会有所不一样。具体缘由未知。
如下demo与该例子所用的标签有些许不一样,但也能实现demo,具体起因及细节须要研究 AFrame.js 。
大体思路是:
引用框架
在代码中使用框架的语法构建:
使用maker generator 训练出一个特定的maker,下载并在代码中指定该maker文件,maker文件与识别图相关联。
运行demo,使用设备的摄像头对准maker关联的图像,便可看到AR效果
像往常同样构建一个web页面,引入所须要的框架。
<!-- include A-Frame obviously -->
<script src="/aframe.min.js"></script>
<!-- include ar.js for A-Frame -->
<script src="/aframe-ar.js"></script>
<!-- include A-Frame-Extras -->
<script src="/static/js/aframe-extras.min.js"></script>
复制代码
使用AFrame的标签,相似HTML的写法来实现AR效果
<body style='margin : 0px; overflow: hidden;'>
<!-- 构建一个3d场景 -->
<a-scene embedded arjs>
<!-- 设置一个识别图,这个很重要,AR效果能不能显示出来全凭这张识别图是否被识别 -->
<a-marker preset='custom' type='pattern' url='/static/marker/test/20/pattern-marker(2).patt'>
<!-- load gltf model 加载一个GLTF格式的模型,该模型就是咱们想渲染到屏幕上的效果-->
<a-entity gltf-model="/static/gltf/CNtower.glb" scale='0.01 0.01 0.01' rotation="-90 0 0"></a-entity>
<!-- a-entity标签也能渲染一个模型,animation-mixer属性还可也添加动效,理解具体细节须要参考AFrame.js文档 -->
<!-- <a-entity gltf-model="/static/gltf/scene.gltf" animation-mixer scale="1 1 1" rotation="-120 0 0" position="0 0.5 0"></a-entity> -->
<!-- 或者像这样 渲染一个立方体 -->
<!-- <a-box position='0 0.5 0' material='color: black;'></a-box> -->
</a-marker>
<!-- add camera 添加一个摄像机,写法也不一样,具体须要看文档-->
<!-- <a-entity camera id="my"></a-entity> -->
<a-camera ar-raycaster raycaster cursor="fuse:false"></a-camera>
</a-scene>
</body>
复制代码
一、因为项目运行在web中,所以web环境的兼容性很大程度取决于用户运行环境的浏览器内核。目前webAR所依赖的技术始终逃不了 webRTC 、webGL 、若是运行环境(浏览器)连这两我的特性都没法支持,则没法进行下一步。
经测试IOS版本微信和QQ内置的浏览器均没法支持这两个特性,折中的办法是提示用户使用Safari进行体验。安卓端尚可。
二、AR最核心的是识别与追踪,web领域的js版artoolkit不像Apple的ARCore 和Google的ARKit那样强大,并且业界还没造成一个成熟的解决方案,只有一些规范,草案等。
基于maker识别图来进行识别和追踪是一个比较高效的作法,受限于识别算法和摄像机追踪的能力有限,因此上述demo对识别图有着很是高的要求,通过测试28张识别图,若是不按规则来设定识别图则会致使识别失败。设备摄像头须要离识别图很是近不然模型抖动会很是明显,严重影响体验。
若是抛开依赖识别图这种方法,目前尚未解决方案。
因此从体验上看,目前最大的问题是识别图的识别率低且有特定要求,模型抖动剧烈影响体验,与模型交互困难。页面一直处于视频流状态会致使设备发热,耗电量大幅上升。
三、在3D场景渲染,模型渲染这一层面,首先须要对底层的webGL有必定熟悉程度,最重要的是three.js这个框架,或是通过封装的AFrame,它们用来构建3d场景和3d模型须要对这个框架有很深刻的了解,如何与模型进行交互等等,这些将致使一些学习成本。
通过测试,超过1MB的GITF2.0模型 使用AFrame加载不出,具体缘由还须要进一步分析,
四、国内外对webAR 的讨论和demo 案例目前都比较少,可以搜到的资料几乎都是英文版。成熟的产品更少,阴阳师的AR抽取SSR卡牌的也是基于maker图来实现,且抖动明显,追踪能力也比较差。王者荣耀刚刚更新在英雄界面可以显示AR效果目前也只在特定的OPPO联合开发机型中实现,何况这两款产品是更强大的APP端。
本文部份内容节选自如下参考文章
Web-Powered Augmented Reality: a Hands-On Tutorial
Augmented Reality in 10 Lines of HTML - AR.js with a-frame magic
Developing Augmented Reality For The Web Using AR.Js
Build and access your first AR webapp in less than 10mn using ARjs
Using 3D models with AR.js and A-Frame