如何在 Web 上构建虚拟现实

有人认为虚拟现实将在 2020 年达到 70 亿美元的价值。在那之前,web 肯定不会一直停留于 2D 环境。实际上,已经有一些简单的方法可以将虚拟现实带进浏览器了。而且那弄起来也非常有趣!

要开始你的虚拟 Web 开发之旅,有这么三种可行的方式:

我会将每一种方式都过一遍,简要展示下它们各自是如何工作的。

JavaScript,Three.js 和监视设备朝向

当前,大多数基于浏览器的虚拟现实项目都是利用浏览器的 deviceorientation 事件。此事件告诉浏览器设备的朝向,而且允许浏览器在设备旋转或倾斜时有所动作。从虚拟现实的角度看,此功能允许你侦测到某人看向某个方向,然后你可以调整摄像头以跟随他的视线。

为了在浏览器里获得良好的 3D 场景,我们使用一个可以方便地创建 3D 形状和场景的 JavaScript 框架three.js。它封装了创建 3D 内容的大部分复杂性,让你可以专注于把你希望的东西放进你的场景。

我在 SitePoint 上写过两个使用设备朝向方法的示例:

如果你不熟悉 three.js 和组建场景,我推荐你看一下上面的两篇文章以更深入的理解此方法。我将只大致介绍下主要概念。

下面是要用到的关键 JavaScript 文件(你可以从上面的示例中获取,也可以 从three.js 例子下载):

three.min.js– three.js 框架

DeviceOrientationControls.js– 这是一个 three.js 插件,它帮助我们完成之前提到过的监视设备朝向,可以另摄像头根据设备的移动进行调整。

OrbitControls.js– 这是一个备用的控制器,它可以在没有设备朝向事件的时候用鼠标调整摄像头。

StereoEffect.js– 这是一个 three.js 的效果插件,可以针对每只眼睛对画面进行细微的角度调整,就像虚拟现实该有的立体效果。这使得我们不用做任何复杂的工作,就可以创造实打实的虚拟现实分屏效果。

设备朝向

使用设备朝向控制的代码大致如下:

function setOrientationControls(e) {
  if (!e.alpha) {
    return;
  }
  controls = new THREE.DeviceOrientationControls(camera, true);
  controls.connect();
  controls.update();
  element.addEventListener('click', fullscreen, false);
  window.removeEventListener('deviceorientation', setOrientationControls, true);
}
window.addEventListener('deviceorientation', setOrientationControls, true);
function fullscreen() {
  if (container.requestFullscreen) {
    container.requestFullscreen();
  } else if (container.msRequestFullscreen) {
    container.msRequestFullscreen();
  } else if (container.mozRequestFullScreen) {
    container.mozRequestFullScreen();
  } else if (container.webkitRequestFullscreen) {
    container.webkitRequestFullscreen();
  }
}

在可用设备上,设备朝向事件监听器提供一组 alpha,beta 和 gamma 值。如果没有 alpha 值就不能通过设备朝向进行控制,转而替代的是轨道控制。

如果有 alpha 值,那么我们就可以使用设备朝向控制摄像头。如果用户轻击屏幕,我们还可将场景在全屏模式下呈现(我们可不想在虚拟现实下看到浏览器地址栏)。

轨道控制

如果 alpha 值不存在,我们也就不可以访问设备的定位事件,这替代了通过摄像头拖拽鼠标的技术。这看起来就像这样:

controls = new THREE.OrbitControls(camera, element);
controls.target.set(
  camera.position.x,
  camera.position.y,
  camera.position.z
);
controls.noPan = true;
controls.noZoom = true;

主要可能混乱的代码是上面的 noPan 和 noZoom。基本上,我们不需要通过鼠标移动身体的场景,我们也不希望能够放大或缩小 —— 我只是想环视。

立体效果

为了使用立体效果,我们先这么定义:

effect = new THREE.StereoEffect(renderer);

然后再窗口重设尺寸时,相应更新它的尺寸:

effect.setSize(width, height);

在每次 requestAnimationFrame 的时候,使用效果渲染场景:

effect.render(scene, camera);

以上便是使用设备朝向方法达到虚拟现实的基本方法。这种方法对于简易的 Google Cardboard 实现效率还可以,但在 Oculus Rift 上就不是太高效了。下面要介绍的方法在 Rift 上表现得要好得多。

JavaScript,Three.js 和 WebVR

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/61bc947e20ab7307d7db8dd6ee607458.html