WebVR开发教程——交互事件(一)头显与手柄

前两期主要介绍了开发WebVR应用的基本套路,不过开发出来的场景还只是“可远观而不可亵玩”,缺少交互性,本期将带你们走进VR交互世界,看看WebVR事件是如何开发的。dom

VR交互有哪些?

在可交互的VR世界里,用户再也不只是个观察者,而是虚拟世界中一个生命,能够与虚拟世界进行通讯。这种通讯应该是双向的:虚拟场景能感知你的存在(位置、方向),同时你的输入又对物体产生做用。这里借鉴一个VR游戏场景:ide

  1. 一位MM想让你给她选衣服,弹出一个菜单让你选,你用touchpad滑动选择给MM装扮,你选了一条裙子并点击手柄的按钮确认;
  2. MM问你看起来好很差看,你赶忙点头;
  3. MM很高兴,让你给她拍照,这时候你的手柄已变成了相机,对准她按下按钮就能够拍照;
  4. 然而你二话不说蹲下去想欣赏MM的裙底,结果MM生气了,游戏结束!
    VR女朋友——点头与摇头

上述共采用了四种交互方式,根据输入设备可分为headset头显交互和gamepad手柄交互,前者经过头显行为触发事件(如二、4),后者经过手柄行为触发事件(如一、3)。this

这些交互行为都须要硬件支持(好比陀螺仪和加速计提供方向追踪支持),咱们须要经过JavaScript API来获取headset或者gamepad的动态数据。google

因为各VR产商的头显和手柄具备差别,所以对于用户交互层面的支持度也良莠不齐,如下展现各主流VR平台在头显和手柄方面的在交互上的支持状况。spa

VR类型 |headset|gamepad
:------------:|:------------:|:------------:
Cardboard|3-DoF|无
Daydream Smartphone VR|3-DoF|3-DoF
Daydream Standalone VR|6-DoF|?-DoF
Gear VR|3-DoF|3-DoF
Oculus Rift|6-DoF|6-DoF
HTC Vive|6-DoF|6-DoF
Microsoft MR|6-DoF|6-DoF调试

表中的DoF(degree of freedom)就是咱们常说的自由度,主要为Orientation自由度和Position自由度两种。code

  • Orientation自由度,支持方向追踪,通常由陀螺仪、加速计等传感器支持
  • Position自由度,支持位置追踪,通常分为outside-in(外向追踪)的红外追踪技术和inside-out(内向追踪)的SLAM技术支持

一般在VR体系里,3-DoF指的是VR硬件支持Orientation,6-DoF指的是支持Orientation + Position。对象


Headset交互事件

Headset交互根据自由度可分为3-DoF和6-DoF,显然,全部的VR头显都应支持Orientation方向的3-DoF追踪。教程

  • 3-DoF依赖于设备的陀螺仪和加速计支持,根据头部朝向来渲染场景视角,能够支持gaze注视和摇头点头的行为,通常以手机VR为主;
  • 6-DoF则指的是支持空间追踪,因为能够感知空间移动,能够支持Lean, dodge, duck的交互方式,如Oculus Rift和Htc Vive,以及Microsoft MR和Daydream Standalone等。

DoF of Headset

实现headset交互,首先是要能看获得虚拟世界,上期WebVR深度剖析中VR渲染是实现headset交互的第一步,咱们须要使用WebVR API来获取headset数据。three

这里再复习一下:当用户戴着headset扭头或走动时,渲染器在每帧经过VRFrameData的视觉-投影矩阵,动态计算出每一个物体的MVP复合矩阵,最后进行顶点和片元绘制。
使人兴奋的是,three.js已经将这个过程封装到了相机和渲染器中,帮咱们实现了第一步。

第二步,咱们须要让三维场景感知用户(头部)的存在,举个例子,当一个球朝着玩家丢过来的时候,玩家机灵一躲,程序根据球体与玩家的位置判断玩家是否躲闪成功。
6-DoF交互:躲闪小球
这时候,咱们还须要用到VRFrameData一个重要属性pose,经过frameData.pose返回一个VRPose对象,可获取headset的传感器信息,好比位置、方向、速度和加速度等。

VRPose

属性|类型|说明
:------------:|:------------:|:------------:
position|Float32Array|返回headset的位置矩阵
orientation|Float32Array|返回headset的方向矩阵
angularAcceleration|Float32Array|返回x, y, z轴每秒的角加速度
angularVelocity |Float32Array|返回x, y, z轴每秒的角速度
linearAcceleration|Float32Array|返回x, y, z轴每秒的线性加速度
linearVelocity |Float32Array|返回x, y, z轴的线性速度

经过这几个属性,咱们可让相机具有物理数据,拥有实体感知能力,而不仅仅只是观察者模式。

好比,下面实现用户在使用HTC Vive此类6-DoF的headset时,走动超过范围弹出警告的功能:

update() {
  const { vrdisplay, frameData, userModel } = this; 
  frameData = vrdisplay.getFrameData(frameData);
  const vrpose = frameData.pose;
  userModel.position.fromArray(vrpose.position); // 将VRPose位置矩阵赋予用户角色
  const { x, y, z } = userModel.position; // 解构用户位置的x,y,z坐标
  if ( Math.abs(x) > 20 || Math.abs(y) > 20 || Math.abs(z) > 20 ) {
    // 当用户离初始点超过20×20×20的空间时,弹出警告
    showWarningToast();  // 展现警告框
  }
}

一样,three.js在VR模式下会自动将VRPose的positionorientation转化成camera的Object3D属性,所以咱们能够直接调用camera.positioncamera.quaternation/rotation获取用户的位置和朝向,代码简化以下:

update() {
  const { camera, userModel } = this;
  userModel.position.copy(camera.position);
  const { x, y, z } = userModel.position; // 解构用户位置坐标
  if ( Math.abs(x) > 20 || Math.abs(y) > 20 || Math.abs(z) > 20 ) {
    showWarningToast();  // 用户离初始点超过20×20×20的空间时,弹出警告框
  }
}

基本的headset交互事件就是这样,理解了这些,咱们能够实现gaze事件监听,点头摇头事件监听等。


GamePad交互事件

除了headset,如今大部分VR还搭配gamepad,用户经过手持手柄能够与虚拟场景进行交互。

对于gamepad手柄而言,也有3-DoF和6-DoF的两种类型:

  • 3-DoF如daydream controller,只支持方向追踪,因而google推荐采用laser激光笔进行交互。
  • 6-DoF如Oculus touch,能够进行方向和位置追踪,所以能够很好的模拟手臂的动做。

相比headset传感器输入产生的交互,gamepad还多了各类输入元件,如按钮、touchpad触控板或thumbstick手摇杆等。

因而,根据手柄输入硬件又可将gamepad事件分为三类:

A. 传感器事件:由传感器对手柄进行物理追踪,如激光笔交互;
B. 按钮事件:经过点击按钮产生的交互行为;
C. 控制单元事件:由thumbstick, touchpad输入产生,如swipe滑动来翻页等。

那么如何实现gamepad的交互事件呢?其实换个问题就是:如何访问手柄的硬件信息,答案是使用Gamepad API,详见WebVR开发教程——交互事件(二)使用Gamepad


WebVR开发传送门:

WebVR开发教程——深度剖析 关于WebVR的开发调试方案以及原理机制
WebVR开发教程——标准入门 使用Three.js开发WebVR场景的入门教程

相关文章
相关标签/搜索