WebXR 是标准也是概念,指的基于 Web 实现虚拟现实和增强现实的能力。其实就是在 Web 上开发 AR(Augmented Reality)和 VR(Virtual Reality)应用的 API, “X”代表沉浸式体验中的任何事物。
API
-
API 演进:主要是 google 在推进,从 2016 年开始提出的 WebVR 标准,到由于缺了增强现实这一块,2018 年改为 WebXR[1]
-
相关 API 示例:immersive-web.github.io/webxr-sampl…[2]
-
最新动态:2021 年 4月13日 Chrome 的 90 版本增加新 WebXR API:
-
WebXR Depth API:获取用户的设备与现实环境中物体的距离
-
WebXR AR Lighting Estimation:获取环境的光线情况
-
示例代码:
async function activateXR() {
// 创建 WebGL 上下文
const canvas = document.createElement(“canvas”);
document.body.appendChild(canvas);
const gl = canvas.getContext(“webgl”, { xrCompatible: true });
// 初始化three.js
const scene = new THREE.Scene();
// 创建一个有不同颜色面的立方体
const materials = [
new THREE.MeshBasicMaterial({ color: 0xff0000 }),
new THREE.MeshBasicMaterial({ color: 0x0000ff }),
new THREE.MeshBasicMaterial({ color: 0x00ff00 }),
new THREE.MeshBasicMaterial({ color: 0xff00ff }),
new THREE.MeshBasicMaterial({ color: 0x00ffff }),
new THREE.MeshBasicMaterial({ color: 0xffff00 })
];
// 将立方体添加到场景中
const cube = new THREE.Mesh(new THREE.BoxBufferGeometry(0.2, 0.2, 0.2), materials);
cube.position.set(1, 1, 1);
scene.add(cube);
// 使用three.js设置渲染:创建渲染器、挂载相机
const renderer = new THREE.WebGLRenderer({
alpha: true,
preserveDrawingBuffer: true,
canvas: canvas,
context: gl
});
renderer.autoClear = false;
// API 直接更新相机矩阵
// 禁用矩阵自动更新
const camera = new THREE.PerspectiveCamera();
camera.matrixAutoUpdate = false;
// 使用“immersive-ar”初始化 WebXR 会话
const session = await navigator.xr.requestSession(“immersive-ar”);
session.updateRenderState({
baseLayer: new XRWebGLLayer(session, gl)
});
const referenceSpace = await session.requestReferenceSpace(‘local’);
// 创建一个渲染循环,允许我们在 AR 视图上绘图
const onXRFrame = (time, frame) => {
session.requestAnimationFrame(onXRFrame);
// 将图形帧缓冲区绑定到 baseLayer 的帧缓冲区
gl.bindFramebuffer(gl.FRAMEBUFFER, session.renderState.baseLayer.framebuffer)
// 检索设备的姿态
// XRFrame.getViewerPose 可以在会话尝试建立跟踪时返回 null
const pose = frame.getViewerPose(referenceSpace);
if (pose) {
// 在移动端 AR 中,只有一个视图
const view = pose.views[0];
const viewport = session.renderState.baseLayer.getViewport(view);
renderer.setSize(viewport.width, viewport.height)
// 使用视图的变换矩阵和投影矩阵来配置 THREE.camera
camera.matrix.fromArray(view.transform.matrix)
camera.projectionMatrix.fromArray(view.projectionMatrix);
camera.updateMatrixWorld(true);
// 使用 THREE.WebGLRenderer 渲染场景
renderer.render(scene, camera)
}
}
session.requestAnimationFrame(onXRFrame);
}
-
兼容性:作为 W3C 的前沿标准,目前主要是 Chrome 在推进。市面上浏览器对 WebXR 的支持整体较弱,后面会介绍相关的兼容库和现成的解决方案。
模型观察者:model-viewer[3]
- 谷歌实现的一个 web component,可用于查看 Web 上的 3D 模型并与之交互
<model-viewer src=“https://modelviewer.dev/shared-assets/models/Astronaut.glb”
ios-src=“https://modelviewer.dev/shared-assets/models/Astronaut.usdz”
alt=“A 3D model of an astronaut”
ar
auto-rotate
camera-controls>
- 实际效果:
Unity
作为知名的 3d 游戏引擎,也有相应的 WebWR 支持库
- unity-webxr-export:github.com/De-Panther/…[4]
社区生态
- XR Swim[5]:为开发者提供了一个发布 WebXR 内容的统一平台,相当于网页端 AR/VR 应用领域的 Steam 平台。
挑战
-
如何保持低延迟、高精度的场景,以及快速处理数据进行渲染和展示动画的能力。
-
传统的通信方法速度不够快。查看场景产生的大量数据可能超出渲染限制。
WebAR
优缺点
和 WebXR 有相似的优缺点。
-
优点:跨平台、传播方便( URL 的格式传播)
-
缺点:
-
各浏览器标准不统一
-
3D 内容加载慢,无法实现复杂的内容
-
渲染质量低
-
无法实现复杂交互(受限于浏览器传统交互方式)
WebAr 框架及关键原理
-
实现 AR 需要:识别、追踪和渲染
-
AR SDK:谷歌 AR 团队(Google AR[6])提供 WebARonARKit, WebARonARCore。均具备运动追踪、环境感知和光线感应等功能。
-
苹果:WebARonARKit[7](源自移动端 ARKit)
-
安卓:WebARonARCore[8](源自移动端 ARCore)
-
主流AR 框架:目前维护和使用比较多的是 AR.js[9],另外还有一些其他的:
-
three.ar.js:github.com/google-ar/t…[10]
-
ARToolKit:www.hitl.washington.edu/artoolkit/[11]
-
JSARToolKit:github.com/kig/JSARToo…[12]
-
argon.js:www.argonjs.io/[13]
-
awe.js:awe.media/#main[14]
-
tracking.js:github.com/eduardolund…[15]
-
AR.js:具备上述提到的从信息获取到处理、渲染绘制的能力。
-
主要是封装了:
-
WebRTC:获取视频流(最关键的 API 方法是 getUserMedia() ,实时获取摄像头的视频流)
-
JSARToolKit[16]:主要提供了识别和追踪 marker 的功能。(1999 年发布,一直更新至今)
-
Three.js、Babylon.js、A-Frame(这几个都是基于 WebGL 的渲染库)
-
用十行 HTML 就实现 AR[17]:
-
效果如下:codepen 地址[18]、识别图片地址[19]
-
还有一些独立功能的框架:
-
A-Frame:基于 Three.js 的开源框架,可以在 HTML 中直接配置场景,适用于简单的 3D 场景搭建
-
方式一:在前端直接处理视频流。在前端直接进行图像处理,可以用 Tracking.js 和 JSFeat。这两个库类似,都是在前端做计算机视觉的,包括提取特征点、人脸识别等。
-
方式二:前端传输视频流给后端,后端处理完毕返回结果到前端,目前有一些云识别服务就是如此。
-
识别与追踪:Tracking.js、JSFeat、ConvNetJS、deeplearn.js、keras.js 。获取到视频流之后的工作就是识别和追踪。不管是对于 native AR 还是 WebAR,目前的识别算法与框架已经非常成熟,难就难在识别之后如何跟踪,如何更好更稳定更高质量的跟踪。
-
渲染与交互:A-Frame[20]、Three.js、Babylon.js、Pixi.js、WebGL
-
框架库实现原理:上面提到的 AR 框架实现原理大都如下图所示:
性能方案
-
把纯计算的代码移到 WebGL 的 shader 或 Web Worker 里
-
适用于事先计算或实时性要求不高的代码,如布局算法
-
shader 可以用于加速只和渲染(重绘)有关的代码,无关渲染的代码放入 shader 中反而会造成重复计算
-
WebGL 调用 GPU 加速
-
Web Worker
-
WebAssembly
-
gpu.js[21]
-
将简单的 JavaScript 函数转换为着色器语言并编译它们,以便它们在您的 GPU 上运行。如果 GPU 不可用,函数仍将在常规 JavaScript 中运行。
-
用滤波算法(比如卡尔曼滤波)将卡顿降到更小,让用户从视觉感受上似乎更流畅
市场化解决方案
-
Kivicube:www.kivicube.com/[22]
-
创建 AR、VR 与 3D 场景,并在通用的 Web 平台上分享它们
-
AR Quick Look:www.kivicube.com/ar-quick-lo…[23]
-
示例:访问地址[24]、识别图片地址
-
EasyAR:www.easyar.cn/[25]
-
支持WebAR、小程序 AR、Sense 跟踪能力,还提供云识别、姿态\手势识别服务
-
8th Wall:www.8thwall.com/[26]
-
集创造、协作和发布增强现实项目于一体的平台,不需要第三方软件,服务器设置或外部工具,只需登录,编码,然后点击发布
-
创建了一个端到端云解决方案,用于创建、协作和即时发布基于浏览器的 WebAR 项目
-
示例:github.com/8thwall/web…[27]
-
Apple AR Quick Look:www.kivicube.com/ar-quick-lo…[28]
-
给开发者提供了便捷的3D模型预览和分享的工具
-
iPhone 和 iPad 的应用程序或者网站中嵌入 Quick Look 视图,以 3D 或 AR 形式显示虚拟对象的 USDZ 文件
扩展
–
-
企业 AR:2021 年的 7 个实际用例:arvrjourney.com/enterprise-…[29]
-
主流领域:远程协助、医疗诊断、销售、培训、物流、制造、原型设计
相关资料
-
Google AR:
-
github:github.com/google-ar[30]
-
AR Core 站点:developers.google.com/ar[31]
-
WebXR:
-
google:developers.google.com/ar/develop/…[32]
-
w3c:www.w3.org/TR/webxr/[33]
-
相关 API 官方示例:immersive-web.github.io/webxr-sampl…[34]
-
MDN:developer.mozilla.org/zh-CN/docs/…[35]
-
A Gentle Introduction To WebXR:arvrjourney.com/a-gentle-in…[36]
-
WebAR与小程序AR极速入门教程:juejin.cn/post/695158…[37]
-
万字干货介绍WebAR的实现与应用:mp.weixin.qq.com/s\?\_\_biz=Mzg…[38]
-
Web 前端中的增强现实(AR)开发技术:segmentfault.com/a/119000001…[39]
-
Augmented Reality in 10 Lines of HTML:medium.com/arjs/augmen…[40]
-
资源:
-
Mixamo:www.mixamo.com/#/[41]
关于本文
总结
大厂面试问深度,小厂面试问广度,如果有同学想进大厂深造一定要有一个方向精通的惊艳到面试官,还要平时遇到问题后思考一下问题的本质,找方法解决是一个方面,看到问题本质是另一个方面。还有大家一定要有目标,我在很久之前就想着以后一定要去大厂,然后默默努力,每天看一些大佬们的文章,总是觉得只有再学深入一点才有机会,所以才有恒心一直学下去。