666!让移动端也用上3D·VR特效

虽说近来势头被AI盖过了,但VR、AR技术自前年以来,一直在风口浪尖。HTC、SONY的VR眼镜,微软的HoloLens、苹果的ARkit,甚至连任天堂的五毛钱特效AR游戏Pokémon Go都借机火了一把。作为号称“走在宇宙前沿,五个月换一个新框架”的web前端开发,怎么能错过这波车呢?

从WebGL说起

要在web页面实现VR或者AR场景,离不开3D模型的构建,这就不得不提到WebGL。WebGL,全称WebGraphics Library,是一套用于在任何兼容的Web浏览器中呈现交互式3D和2D图形,而无需使用插件的JavaScriptAPI。它被整合在浏览器中,利用GPU加速和图像处理,直接在canvas元素上进行渲染,可以无缝地与其他页面元素整合在一起。

WebGL的接口很多,但是使用起来并不方便,缺乏有效的3D对象操作方法。为此,threeJS应运而生。得益于WebGL的不断进化,threeJS在此基础上构建了一个跨浏览器的3D动画引擎,支持场景、相机、光照、材质、网格、粒子系统、物理引擎等特性。此外还提供众多开源库,支持添加设备方向检测,自定义控制器,立体眼镜支持,分屏渲染一系列功能。因此,本次移动端的360全景漫游就是利用threeJS+设备方向检测制作而成。

 

移动端360全景漫游原理

360全景漫游的原理并不复杂,主要分为两部分:

1、360全景的构建;

2、摄像机视口的控制。

为了节省资源,360全景的构建通常用贴图完成,将场景的全景图制作成map图片,映射到一个封闭的几何体内表面。常用的贴图映射方法主要有立方体,球面,以及柱面图。立方体映射是将全景图制作为6张正方形贴图,分别贴到正方体的六个内表面。球面和柱面则是制作场景的球面或者柱面展开图,映射到球体或柱体的内表面。至于摄像机视口的控制,则可以直接调用threeJS的设备方向检测开源库,利用内置传感器,实现摄像机视口与移动终端屏幕的同步。即摄像机视口跟随着屏幕朝向一起运动。

位于柏林的索尼中心内景360球面展开

立方展开示意图 

 

渲染器的选择

threeJS利用渲染器进行渲染。在移动端实现3D场景,或者360全景漫游,最关心的应该是响应性能和加载速度。移动设备的处理能力和网络速度通常较弱,如果响应速度太差或者需要加载大量资源,那么在移动端实现3D场景就失去意义了。因此,渲染器的选择格外重要。threeJS提供三种渲染器:webglrender,canvasrender和css3drender。webglrender使用WebGL的api,直接在canvas渲染场景,功能强大,可以利用GPU硬件加速。canvasrender不使用webgl,直接在canvas上面渲染场景,速度较慢,适用于一些不支持webgl的设备。而css3drender直接使用html元素,通过css3的transformmatrix3d属性,操作html元素来旋转、移动3D对象。

乍一看,似乎css3drender是最适合移动端开发的渲染器,它不需要WebGL,仅仅利用css3的transform,性能和兼容性应该都较优。但事实上并非如此。css3drender用html元素模拟3d对象,意味着每一个3d对象都是一个html元素。当元素移动时,该元素的css都会重置,操作大量元素时渲染成本很高。而且元素采用transformmatrix3d定位,计算误差较大,某些时候会出现元素重叠和错位。

而之前觉得WebGL需要GUP加速,可能在低端手机上表现不好,实际上却是多虑了。WebGL将全部3D对象都渲染到一个canvas上,页面负担较小。目前现在市面上的大部分移动端浏览器都是chrome内核,对WebGL支持度很高,而且智能移动设备大多配备了GPU,很少出现硬件不支持的情况。

所以在移动端构建3D场景,使用webglrender更合适。

用户交互的实现

移动端的交互方式通常有两种:一种是构建全景场景,利用加速度计,让用户在场景中漫游。一种是在固定场景中展示某个3D物体,用户通过触摸屏与3D物体互动。全景漫游的方式很简单,只要引入设备方向检测插件就可以。比较难处理的是与场景物体的互动。

如果是使用webglrender渲染的3D物体,那么只能把这个物体做成网格模型,通过射线交叉的方式获取当前用户点击坐标对应的物体。这样做比较麻烦,需要自己定义点击事件、拖动事件,并有可能因为网格格式导致物体无法与射线交叉。网格模型的数据量通常很大,一个很小的标签模型往往就是几百KB大小。所以,除非需要与场景物体做复杂的交互,否则不要采用webglrender直接渲染。

移动端3D场景中最常见的交互方式是点击。用户点击一个物品,一个区域,然后场景进行下一步操作,比如弹窗,镜头切换之类的。这种交互用WebGL处理性价比会很低,比较好的做法是把可点击元素直接做成html元素,由css3drender直接渲染到场景中。因此我们还可以像普通的html节点一样处理这些元素,绑定各种touch事件,加入各种css效果,并省去引入网格模型的开销,大大提高了开发效率。

 

一个标签网格模型需要107 KB,而PNG图片仅仅2KB

提高加载速度和兼容性检测

在移动端制作3D场景,加载速度也是一个重要关注点。

threejs库文件本身压缩后有500k左右,制作一个分辨率过得去的全景漫游通常需要六张1024px*1024px的jpg图片,大小在1.5M~2M之间,此外还有3D网格模型,每个模型都会在400K以上。所以带有threejs场景的移动端页面直接加载会特别慢,若把threejs放在head引入,还会导致页面失去响应,亟需优化。

目前采取的做法是:

  • 把threejs库动态载入,并在onload后再构建场景;

  • 先给用户一个普通页面,等用户进入站点后,再偷偷threejs需要的材质、贴图;

  • 贴图加载完成后立刻渲染场景,不要等待用户进入3D页面后再渲染,防止首次渲染过慢导致的空白屏。

除此之外,还要考虑某些浏览器不支持threejs的情况。开发文档上建议使用封装好的detector.js检查兼容性,然而实际上这个库并不准确,而且也无法检测内存耗尽导致的错误。因此最好还是结合try...catch...来使用,在可能出现不支持的位置捕获错误,弹出错误提示,争取给低版本浏览器较好的体验。

 

结语

在移动端引入3D场景,制作全景漫游、VR效果并不困难。数据量、兼容性和运行性能也在可以接受的范围内。对于某些需要3D展示的站点,这或许是一个值得一试的方案。

所以,最后的最后,附上一个小demo ~~~

 

网易云信 IM 红包上线啦!最快3小时集成红包功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值