注:基于官方的.bs规范专用格式进行了翻译,但结果发现无法编译成html格式,所幸基本兼容.markdown格式。

中文翻译项目地址:https://github.com/web3d/webvr-spec/blob/master/webvr-zh_CN.bs 欢迎加入。

WebVR

Status: ED
ED: https://github.com/MozVR/webvr-spec/blob/master/webvr.html
Shortname: webvr
Level: 1
Editor: Vladimir Vukicevic, Mozilla http://mozilla.com/, vladimir@mozilla.com
Editor: Brandon Jones, Google http://google.com/, bajones@google.com
Abstract: This specification describes support for accessing virtual reality devices, including sensors and head-mounted displays on the Web.
Mailing List: web-vr-discuss@mozilla.org
Mailing List Archives: https://mail.mozilla.org/pipermail/web-vr-discuss/

简介 # {#intro}

硬件使得那些需要高精度、低延时界面效果的虚拟现实应用能提供令人满意的体验。其他接口如设备定位事件传感器虽然可以被应用到VR场景的输入,但削弱了这种接口的原始用途,且经常满足不了对高质量VR效果的精度需求。

WebVR的API给VR硬件定义了专门定制的接口,让开发者构建出沉浸感强、舒适度高的VR体验。

支持的设备类型 # {#devtypes}

目前定义了两种VR设备体(Variant),每种设备体仅描述一款硬件其中某一种特定功能,而不是该硬件所有功能。例如,Oculus Rift这样典型的头盔式显示器将被对外定义成两个VR设备:

HMDVRDevice:描述了该设备的光学属性,包括:视角、瞳距;

PositionSensorVRDevice:描述了该HMD设备在空间上的方位;

PositionSensorVRDevice可以不提供HMDVRDevice相关的功能,比如仅仅是一个六自由度控制器可以跟踪方位即可。

更多的VRDevice类型会随着消费者不断接触到的新硬件类型或新功能逐渐增加,比如眼动跟踪仪就很可能是将来的一种接口设备。

安全性 # {#security}

关于安全问题的信息会放到这段。

DOM 接口 # {#dom}

要支持在运行时访问上述功能,需向HTML DOM中添加相应接口或功能的代码,该小节对其做了描述。

VREye

enum VREye { "left", "right" };

VRFieldOfView

{{VRFieldOfView}} 接口代表人眼的视角,给出了 从中心点描述场景视图的四个角度。

interface VRFieldOfViewReadOnly {
readonly attribute double upDegrees;
readonly attribute double rightDegrees;
readonly attribute double downDegrees;
readonly attribute double leftDegrees;
}; dictionary VRFieldOfViewInit {
double upDegrees = 0.0;
double rightDegrees = 0.0;
double downDegrees = 0.0;
double leftDegrees = 0.0;
}; [Constructor(optional VRFieldOfViewInit fov),
Constructor(double upDegrees, double rightDegrees, double downDegrees, double leftDegrees)]
interface VRFieldOfView : VRFieldOfViewReadOnly {
inherit attribute double upDegrees;
inherit attribute double rightDegrees;
inherit attribute double downDegrees;
inherit attribute double leftDegrees;
};
以下js代码片段创建了一个兼容WebGL代码的{{VRFieldOfView}}投影矩阵。

function fieldOfViewToProjectionMatrix(fov, zNear, zFar) {
var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0);
var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0);
var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0);
var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0);
var xScale = 2.0 / (leftTan + rightTan);
var yScale = 2.0 / (upTan + downTan); var out = new Float32Array(16);
out[0] = xScale;
out[1] = 0.0;
out[2] = 0.0;
out[3] = 0.0;
out[4] = 0.0;
out[5] = yScale;
out[6] = 0.0;
out[7] = 0.0;
out[8] = -((leftTan - rightTan) * xScale * 0.5);
out[9] = ((upTan - downTan) * yScale * 0.5);
out[10] = -(zNear + zFar) / (zFar - zNear);
out[11] = -1.0;
out[12] = 0.0;
out[13] = 0.0;
out[14] = -(2.0 * zFar * zNear) / (zFar - zNear);
out[15] = 0.0; return out;
}

VRPositionState

{{VRPositionState}} 接口代表传感器在给定时间戳的状况。

interface VRPositionState {
readonly attribute double timeStamp; readonly attribute boolean hasPosition;
readonly attribute DOMPoint? position;
readonly attribute DOMPoint? linearVelocity;
readonly attribute DOMPoint? linearAcceleration; readonly attribute boolean hasOrientation;
// XXX should be DOMQuaternion as soon as we add that
readonly attribute DOMPoint? orientation;
readonly attribute DOMPoint? angularVelocity;
readonly attribute DOMPoint? angularAcceleration;
};

属性 ### {#vrpositionstateattributes}

timeStamp

值的单向增加让开发者可以判断设备的位置状态数据是否更新。既然值是单向增加的,就可以对他们进行比较来判断更新的顺序,因为新的值肯定大于等于旧的值。

hasPosition

为True代表{{position}}可用;为False属性则{{position}}必须为null。

position

代表在指定{{timeStamp}}下传感器的位置,是一个三维坐标。位置是相对原点的距离。原点是怎么来的呢?就是初次读取的传感器位置或者通过调用resetSensor重置传感器时的传感器位置。坐标轴系统定义:

  • X轴正向在向用户右边
  • Y轴正向是向上
  • Z正向是向用户身后

All positions are given relative to the identity orientation. The w component
MUST be 0. 如果传感器无法提供位置数据,就为null。

linearVelocity

在{{timeStamp}}时的线速度。w组件必须为0。如果传感器无法提供位置数据,就为null。

linearAcceleration

在{{timeStamp}}时的线性加速度。w组件必须为0。如果传感器无法提供位置数据,就为null。

hasOrientation

如果{{orientation}}属性可用,则值为true;如果{{orientation}}为null,则值为false。

orientation

在给定的{{timeStamp}}传感器的方位,为四元数。方位偏向(沿Y轴的转角)是相对于传感器的初始偏向的,即初次读取或执行resetSensor时的值。

方位值{x: 0, y: 0, z: 0, w: 1}一般代表“向前”。

如果传感器不能提供方位数据,则返回null。

angularVelocity

给定{{timeStamp}}时传感器的角速度。w组件值必须为0。如果传感器不能提供角速度,则返回null。

angularAcceleration

给定{{timeStamp}}时传感器的角加速度。w组件值必须为0。如果传感器不能提供加角速度,则返回null。

VREyeParameters

{{VREyeParameters}} 接口代表向每只眼正确渲染场景所必须的信息。

interface VREyeParameters {
/* These values are expected to be static per-device/per-user. */
readonly attribute VRFieldOfView minimumFieldOfView;
readonly attribute VRFieldOfView maximumFieldOfView;
readonly attribute VRFieldOfView recommendedFieldOfView;
readonly attribute DOMPoint eyeTranslation; /* These values will vary after a FOV has been set. */
readonly attribute VRFieldOfView currentFieldOfView;
readonly attribute DOMRect renderRect;
};

属性 ### {#vreyeparametersattributes}

minimumFieldOfView

描述眼睛支持的最低视角。

maximumFieldOfView

描述眼睛支持的最大视角。

recommendedFieldOfView

描述眼睛推荐的视角。推荐设置成基于用户校准的值。

eyeTranslation

用户头部正中心到眼睛之间的距离,以米为单位。这个值应该就是代表该用户的瞳距(IPD),但也可以代表头盔中心点到眼球中心点的距离。左眼的值必须是负值,右眼的值必须是正值。

currentFieldOfView

当前眼睛的视角,就是setFieldOfView设置的值。默认为 {{recommendedFieldOfView}} 。

renderRect

描述在画布上渲染给眼睛的可视化内容的视口(viewport)。 左眼和右眼的{{renderRect}}必须不能有交叉, {{renderRect}}中右眼必须是左眼右边的内容。

{{renderRect}}两只眼球合起来应该是描述了HMD在采用{{currentFieldOfView}}时的最佳渲染精度,这样才能用户中心的视角维持在1:1的像素比例。

很多HMD设备会将渲染的图像进行变形处理,来抵消由头盔光学元件带来的不适效果。
画布的光学分辨率经常会比HMD的物理分辨率大,来确保用户看到的最终图像效果是以1:1的比例显示在用户视角中心。
光学画布分辨率可以通过以下方式来计算:

var leftEyeParams = hmd.getEyeParameters("left");
var rightEyeParams = hmd.getEyeParameters("right");
var leftEyeRect = leftEyeParams.renderRect;
var rightEyeRect = rightEyeParams.renderRect; canvas.width = rightEyeRect.x + rightEyeRect.width;
canvas.height = Math.max(leftEyeRect.y + leftEyeRect.height,
rightEyeRect.y + rightEyeRect.height);

VRDevice

{{VRDevice}}接口构成了支持该API的所有VR设备的基础。它包含了如设备ID和描述等一般信息。

interface VRDevice {
readonly attribute DOMString hardwareUnitId;
readonly attribute DOMString deviceId;
readonly attribute DOMString deviceName;
};

属性 ### {#vrdeviceattributes}

hardwareUnitId

各硬件单元的区分标识符,同一款物理硬件中的所有{{VRDevice}}拥有同一个{{hardwareUnitId}}值。

deviceId

区别于物理硬件设备的传感器设备的标识。这个值不会随着浏览器重启而发生变化,可用于关联保存配置数据。

deviceName

用户可读取的标识该设备的名称。

HMDVRDevice

{{HMDVRDevice}}接口代表头盔显示器 {{VRDevice}}。它包含了该HMD的配置和其它信息。

interface HMDVRDevice : VRDevice {
VREyeParameters getEyeParameters(VREye whichEye);
void setFieldOfView(optional VRFieldOfViewInit leftFOV,
optional VRFieldOfViewInit rightFOV,
optional double zNear = 0.01,
optional double zFar = 10000.0);
};

方法 ### {#hmdvrdevicemethods}

getEyeParameters(VREye whichEye)

返回给定眼睛当前的{{VREyeParameters}}.

setFieldOfView(optional VRFieldOfViewInit leftFOV, optional VRFieldOfViewInit rightFOV, optional double zNear = 0.01, optional double zFar = 10000.0)

设置两只眼睛的视角。如果都为null,或者都为0,就会启用{{recommendedFieldOfView}}所设置的值。

如果视角的值超出同一只眼{{minimumFieldOfView}} 或 {{maximumFieldOfView}}的范围,就会自动剪裁到有效范围内。

PositionSensorVRDevice

{{PositionSensorVRDevice}}接口代表传感器{{VRDevice}}能实时报告方位数据(位置、方向可选)。

interface PositionSensorVRDevice : VRDevice {
VRPositionState getState();
VRPositionState getImmediateState();
void resetSensor();
};

方法 ### {#positionsensorvrdevicemethods}

getState()

返回 {{VRPositionState}}的数据词典,包含当前帧(如果在requestAnimationFrame环境中)或前一帧的传感器位置状态。这个状态可以基于帧执行排期的实现机制进行预测。

VRPositionState会包含位置、方向、角度及这些值的加速度值。

可以用{{hasPosition}}和{{hasOrientation}}两个方法来检测相关成员属性是否可用;如果不可用,这些成员属性值必须为null。

getImmediateState()

返回传感器当前瞬时状态。

resetSensor()

重置传感器,把它当前的位置和方向朝向作为设备的原点值。

导航器接口扩展

partial interface Navigator {
Promise<sequence<VRDevice&gt> getVRDevices();
};

方法 ### {#navigatormethods}

getVRDevices()

返回Promise,包含确定可用的{{VRDevice}}列表。应用程序应该遍历该列表,并根据{{hardwareUnitId}}访问设备所有能力。

以下代码代表找出可用的第一款 {{HMDVRDevice}} 以及它相关联的 {{PositionSensorVRDevice}}(如果有的话)。

var gHMD, gPositionSensor;

navigator.getVRDevices().then(function(devices) {
for (var i = 0; i

致谢 # {#ack}

中文翻译:web3d@live.com

[译]WebVR技术方案草案的更多相关文章

  1. 龙之谷手游WebVR技术分享

    主要面向Web前端工程师,需要一定Javascript及three.js基础:本文主要分享内容为基于three.js开发WebVR思路及碰到的问题:有兴趣的同学,欢迎跟帖讨论. 目录:一.项目体验1. ...

  2. Mozilla公布WebVR API标准草案

    随着信息技术的迅速发展,虚拟现实(Virtual Reality,VR)技术在近些年不断完善,其应用范围也变得十分广泛.为了搭建逼真的虚拟场景,VR技术一般都需要用到大量精美的图像和复杂的动作.因此, ...

  3. C#开发BIMFACE系列52 CS客户端集成BIMFACE应用的技术方案

    BIMFACE二次开发系列目录     [已更新最新开发文章,点击查看详细] 在我的博客<C#开发BIMFACE系列49 Web网页集成BIMFACE应用的技术方案>.<C#开发BI ...

  4. 分布式锁1 Java常用技术方案

    前言:       由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题,那么就要利用分布式锁来解决这些问题.所以自己结合实际工作中的一些经验和网上看到的一些资 ...

  5. unity小地图技术方案总结

    技术方案 一:从顶视图获取实时小地图(优点实现快容易对地图进行放大缩小操作而且地图,缺点是不好对地图做出修改,只能在顶部加个另外的相机层来遮盖) 1.创建Redertexture并改名为smallma ...

  6. iOS多线程技术方案

    iOS多线程技术方案 目录 一.多线程简介 1.多线程的由来 2.耗时操作的模拟试验 3.进程和线程 4.多线程的概念及原理 5.多线程的优缺点和一个Tip 6.主线程 7.技术方案 二.Pthrea ...

  7. Facebook存储技术方案:找出“暖性BLOB”数据

    Facebook公司已经在其近线存储体系当中彻底弃用RAID与复制机制,转而采用分布式擦除编码以隔离其所谓的“暖性BLOB”. 暖性?BLOB?这都是些什么东西?大家别急,马上为您讲解: BLOB—— ...

  8. 分布式锁1 Java常用技术方案(转)

    转:http://www.cnblogs.com/PurpleDream/p/5559352.html#3450419 前言:       由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临 ...

  9. Android基于WIFI实现电脑和手机间数据传输的技术方案研究

    Android手机和电脑间基于wifi进行数据传输,从技术上讲,主要有两种方案: 一种是通过ftp协议实现,Android手机作为数据传输过程中的ftp服务器: 一种是通过http协议实现.Andro ...

随机推荐

  1. 每天一个linux命令(53):route命令

    Linux系统的route命令用于显示和操作IP路由表(show / manipulate the IP routing table).要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或 ...

  2. 知方可补不足~Sqlserver中的几把锁和.net中的事务级别

    回到目录 当数据表被事务锁定后,我们再进行select查询时,需要为with(锁选项)来查询信息,如果不加,select将会被阻塞,直到锁被释放,下面介绍几种SQL的锁选项 SQL的几把锁 NOLOC ...

  3. Laravel5.0学习--01 入门

    本文以laravel5.0.22为例. 生产环境建议使用laravel5.1版本,因为该版本是长期支持版本.5.1文档更详细:http://laravel-china.org/docs/5.1. 环境 ...

  4. [数据库连接池二]Java数据库连接池--C3P0和JDNI.

    前言:上一篇文章中讲了DBCP的用法以及实现原理, 这一篇再来说下C3P0和JDNI的用法. 1.1.C3P0数据源 C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规 ...

  5. Android笔记——了解SDK,数据库sqlite的使用

    一.adb是什么? adb的全称为Android Debug Bridge,就是起到调试桥的作用.通过adb我们可以在Eclipse中方面通过DDMS来调试Android程序,说白了就是debug工具 ...

  6. SQLServer数据库备份

    使用sql语句备份数据: BACKUP DATABASE 数据库名称 TO DISK = '存储备份文件的路径\备份名称.bak' WITH INIT 使用例子: BACKUP DATABASE Sh ...

  7. 学习ASP.NET MVC(六)——我的第一个ASP.NET MVC 编辑页面

    在上一文章中由Entity Framework(实体框架)去实现了对数据库的CURD操作.在本篇文章中,主要是调试修改自动生成的动作方法和视图,以及调试编辑功能与编辑功能的Book控制器. 首先,在V ...

  8. 24.编写一个Car类,具有String类型的属性品牌,具有功能drive; 定义其子类Aodi和Benchi,具有属性:价格、型号;具有功能:变速; 定义主类E,在其main方法中分别创建Aodi和Benchi的对象并测试对象的特 性。

    package zhongqiuzuoye; public class Car { String brand; public void drive() {} } package zhongqiuzuo ...

  9. 【WP 8.1开发】自定义(RAW)通知的使用

    继续前面的话题,还是推送通知.上一篇文章中遗留了RAW通知的推送没有给各位演示,特特地留到现在,不为别的,只为这个RAW通知有点意思,玩起来会比较有意思.官方文档将RAW通知译为“原始通知”,这里还是 ...

  10. javase基础复习攻略《九》

    本篇将为大家总结JAVA中的线程机制,谈到线程,大家一定会问线程和进程有什么区别?刚接触进程时我也有这样的疑问,今天就为大家简单介绍一下进程和线程.进程(Process)是计算机中的程序关于某数据集合 ...