Three.js 下的 WebVR 初探

在开始谈 WebVR 前,我们先来看看人眼中的三维立体是如何产生的。

外部世界是三维立体的,但是它在我们的视网膜上留下的投影却是二维的。因为大脑会自动利用视觉信息中的各种深度知觉的线索,“重建”出立体的感知。人眼立体视觉的原理基本是依靠深度知觉+双眼视差

WebVR API 目前还停留在草案阶段,仅能在安装了 Firefox nightly 的 Oculus Rift、Chrome 的实验性版本和 Samsung Gear VR 的浏览器上使用。除了使用原生 API 开发外,目前还可以使用 Mozilla 开发的 A-Frame 框架和 Three.js。本文主要描述的是使用 Three.js 的移动浏览器WebVR体验。

Three.js是一个3D JavaScript 库。封装了底层的图形接口,除了 WebGL 之外,Three.js 还提供了基于 Canvas、SVG 标签的渲染器。2016年天猫双十一宇宙邀请函中酷炫的“一镜到底”就是用的 Three.js 实现的。

创建 Three.js

创建一个 Three.js 的项目,至少包括:

1)渲染器(Renderer)

渲染器决定了渲染的结果应该显示在页面的什么元素上,并以怎样的方式绘制。

以 Canvas 为例,可以绑定渲染器,也可以动态创建渲染器。

2)场景(Scene)

场景只有一种,是所有物体的容器。

3)相机(Camera)

WebGL 和 Three.js 使用的三维坐标轴遵循“右手坐标系”。使用 Three.js 创建的场景是三维的,而通常情况下显示屏是二维的。相机它定义了三维空间到二维屏幕的投影方式。针对投影方式的不同,相机又分为正交投影(OrthographicCamera)与透视投影(PerspectiveCamera)。

正交投影,六个参数分别对应x、y,z轴的最小最大值。它创建一个正射投影矩阵。为了保持相机的横竖比例,需要保证(right - left)与(top - bottom)的比例与 Canvas 宽度与高度的比例一致。

透视投影,四个参数分别是视野在 y-z 平面的角度、投影平面宽高比、近平面(沿Z负轴)的距离,远平面(沿Z负轴)的距离。它创建一个对称的透视投影矩阵。

此外项目中加入光源(Light)与阴影(Shadow)会让场景的渲染效果更加丰富逼真。

我们以 Three.js 官方 examples 中的 WebVR 360° 全景图为例,看看一个完整的 WebVR 项目还依赖哪些 js。

其他 VR 插件

除了引入 Three.js 外,还引入了:

1)VRControls.js

移动浏览器上一般会使用 deviceorientation 事件来检测设备的朝向,WebVR API 可以帮助我们更好的控制设备。使用 VRControls.js,能在 requestAnimationFrame 中不断的获取HMD状态信息并应用到相机(Camera)上。

2)VREffect.js

VREffect.js 会通过 getEyeParameters 获取左眼所视信息,通过获取的可视角度和瞳距用透视投影(PerspectiveCamera)把屏幕 render 为左右两个屏幕,分别对应左右眼,利用深度知觉+两眼视差,让大脑“重建”出立体场景。

3)WebVR.js

WebVR.js 主要提供 WebVR 环境检测,在不兼容 WebVR 体验下的内容提示,以及显示按钮用来“进入”/“退出” WebVR 体验模式。

编写全景图项目

引用完 Three.js 和3个 VR 插件后,就可以开始编写全景图项目主要代码了。

首先需要判断设备是否支持 WebVR,不支持就需要在屏幕上提醒用户。

开始创建渲染器、场景和相机。

接着就是制作360°全景场景,一般可分为球面全景图方式、柱状全景图方式和立方体全景图方式

(球面全景图)


球面全景图虽然具有和人眼最接近的构建模式。但实际制作球面贴图时,因为上下两个顶点处汇集了所有的经线,需要很多立面拼接成一个球体,过于繁琐并且浏览器性能消耗过高。

(柱形全景图)


柱形全景图的垂直视野小,不好做顶部底部的俯仰视角。贴图在侧面虽然最简单,但头顶和脚底是无法观察的区域。

(立方体全景图)


立方体型全景图是由前,后,左,右,上,下6张图片拼接而成。相机位于立方体的中心,也是360°全视角。

贴图相对球形更简单,但是因为是矩形关系,在8个顶点处会有畸变。

在 Three.js 官方示例中,使用的就是立方体全景图。然后再用 Canvas 把全景图片源文件转化为所需数量的贴图面,并用 THREE.Texture 创建纹理贴图对象保存。

因为 VREffect.js 会渲染左右2个屏幕,左相机对应 layers=1 的 skyBox,所以还需要创建一份右相对应 layers=2的skyBoxR。

然后加入 VRControls、VREffect 和按钮。


最后监测一下 window 窗口的大小变化,resize 的时候调整相机角度、更新投影矩阵,调整 WebVR effect 渲染大小。在 requestAnimationFrame 中不断监测设备状态并更新到 Camera 和 WebVR 渲染上。剩下的就是带上 VR HMD 设备查看全景图。

注:

部分图片来自网络

更多 Three.js 和 Web VR 内容,请移步 https://threejs.org和 https://w3c.github.io/webvr

本文作者:陈自然(点融黑帮),高级前端开发,现就职于点融网技术部 Clients 团队。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容