[译]WebVR技术方案草案

简介: 注:基于官方的.bs规范专用格式进行了翻译,但结果发现无法编译成html格式,所幸基本兼容.markdown格式。中文翻译项目地址:https://github.com/web3d/webvr-spec/blob/master/webvr-zh_CN.bs 欢迎加入。

注:基于官方的.bs规范专用格式进行了翻译,但结果发现无法编译成html格式,所幸基本兼容.markdown格式。
中文翻译项目地址:https://github.com/web3d/webvr-spec/blob/master/webvr-zh_CN.bs 欢迎加入。

WebVR

简介 # {#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

目录
相关文章
|
2月前
|
存储 编解码 边缘计算
从RTMPS到MPEG-DASH:直播带货背后的秘密流程
大家好,我是小米,今天聊聊“社区直播带货”的技术流程。文章介绍了RTMPS协议的安全可靠传输,MPEG-DASH的自适应比特率流媒体技术,以及直播数据如何通过边缘节点和数据中心进行高效处理与分发,确保用户流畅观看。通过这些技术,直播带货不仅画质清晰,还保障了安全性和用户体验。希望本文能帮助你深入了解这一流程。如果有任何问题,欢迎留言讨论!
59 2
|
4月前
|
前端开发 API Swift
探索iOS应用开发的新趋势:SwiftUI和Combine框架
【8月更文挑战第16天】本文深入探讨了iOS平台上的两个最新技术:SwiftUI和Combine。SwiftUI旨在简化用户界面的构建,而Combine则优化了事件处理机制。我们将分析这两个框架如何共同推动iOS开发的未来,以及它们给开发者带来的便利和挑战。
96 6
|
6月前
|
前端开发 搜索推荐 iOS开发
探索iOS开发的新纪元:SwiftUI的革命性影响
【6月更文挑战第8天】随着苹果公司推出SwiftUI,iOS开发领域迎来了一场创新风暴。本文将深入探讨SwiftUI如何简化界面构建流程,提升开发者效率,并分析其对现有开发模式的颠覆性影响。我们将通过具体案例,展示SwiftUI在实际开发中的应用和优势。
|
存储 监控 关系型数据库
Instagram 早期技术架构
Instagram 早期技术架构
|
安全 Ubuntu 区块链
IPP模式制度系统开发技术方案丨IPP项目系统开发技术开发程序
IPP模式制度系统开发技术方案丨IPP项目系统开发技术开发程序
162 0
|
机器学习/深度学习 安全 程序员
产品设计不是命题作文:Design Hackathon 方法介绍
在产品的定义阶段,产品发展形态的可能性是最多的。对于当前国内绝大多数移动互联网创业公司来说,在产品定义初期,往往都是由个别产品负责人或者创始人「决定」产品方向的。这种「命题式」的传统方法,会导致产品的大部分可能性被早早扼杀,很容易让产品设计陷入程式化的思维或是已有的产品模式。在这种方式下,不能说诞生不了好的产品,但突破和创新的难度将会大大提高。传统的「头脑风暴」,在发散思维时往往失于天马行空,忽略了落地的可行性。
329 0
产品设计不是命题作文:Design Hackathon 方法介绍
|
JavaScript 前端开发 安全
W3C 发布 WebAssembly 2.0 工作草案
4 月 20 日,W3C 公布了 WebAssembly 2.0 的第一批公共工作草案。
213 0
|
测试技术 开发工具 git
规范语音聊天app开发流程,实现高效开发轻而易举
规范语音聊天app开发流程,实现高效开发轻而易举
|
搜索推荐 算法 SEO
如何做ASO?ASO和SEO有何异同?
有人说SEO已死,小马识途营销顾问并不认同,SEO并不纯粹是一门技术,而是一种思想,只要存在网站,只要存在搜索引擎,SEO的价值就会一直存在。相信搞网络营销的小伙伴对SEO已经耳熟能详,但是对ASO的技巧是否也了如指掌呢?如今,互联网发展如日中天,每日有数以万计的APP应用上线到各大应用市场,这也让SEO的思想延伸到了应用商店,也就是ASO。
3481 0
|
XML Java C#
从Google Wave和XML看软件复杂性之争,互联网营销
  软件公司热衷于雇佣喜欢挑战技术难题的人。表面上看这种做法没什么问题,不幸的是,这会导致公司处于一种情形,你让他们开发一款产品,他们开发的产品更多的是来满足他们对各种技术挑战的好奇心,而不是用来解决客户的问题。
1315 0