forked from MozillaReality/webvr-spec
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathwebvr-zh_CN.bs
340 lines (255 loc) · 13 KB
/
webvr-zh_CN.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
<h1>WebVR</h1>
<pre class='metadata'>
Status: ED
ED: https://github.com/MozVR/webvr-spec/blob/master/webvr.html
Shortname: webvr
Level: 1
Editor: Vladimir Vukicevic, Mozilla http://mozilla.com/, [email protected]
Editor: Brandon Jones, Google http://google.com/, [email protected]
Abstract: This specification describes support for accessing virtual reality devices, including sensors and head-mounted displays on the Web.
Mailing List: [email protected]
Mailing List Archives: https://mail.mozilla.org/pipermail/web-vr-discuss/
</pre>
# 简介 # {#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
<pre class="idl">
enum VREye { "left", "right" };
</pre>
## VRFieldOfView
{{VRFieldOfView}} 接口代表人眼的视角,给出了 从中心点描述场景视图的四个角度。
<pre class="idl">
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;
};
</pre>
<div class="example">
以下js代码片段创建了一个兼容WebGL代码的{{VRFieldOfView}}投影矩阵。
<pre>
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;
}
</pre>
</div>
## VRPositionState
{{VRPositionState}} 接口代表传感器在给定时间戳的状况。
<pre class="idl">
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;
};
</pre>
### 属性 ### {#vrpositionstateattributes}
<dfn attribute for=VRPositionState>timeStamp</dfn>
值的单向增加让开发者可以判断设备的位置状态数据是否更新。既然值是单向增加的,就可以对他们进行比较来判断更新的顺序,因为新的值肯定大于等于旧的值。
<dfn attribute for=VRPositionState>hasPosition</dfn>
为True代表{{position}}可用;为False属性则{{position}}必须为null。
<dfn attribute for=VRPositionState>position</dfn>
代表在指定{{timeStamp}}下传感器的位置,是一个三维坐标。位置是相对原点的距离。原点是怎么来的呢?就是初次读取的传感器位置或者通过调用resetSensor重置传感器时的传感器位置。坐标轴系统定义:
<ul>
<li>X轴正向在向用户右边</li>
<li>Y轴正向是向上</li>
<li>Z正向是向用户身后</li>
</ul>
All positions are given relative to the identity orientation. The w component
MUST be 0. 如果传感器无法提供位置数据,就为null。
<dfn attribute for=VRPositionState>linearVelocity</dfn>
在{{timeStamp}}时的线速度。w组件必须为0。如果传感器无法提供位置数据,就为null。
<dfn attribute for=VRPositionState>linearAcceleration</dfn>
在{{timeStamp}}时的线性加速度。w组件必须为0。如果传感器无法提供位置数据,就为null。
<dfn attribute for=VRPositionState>hasOrientation</dfn>
如果{{orientation}}属性可用,则值为true;如果{{orientation}}为null,则值为false。
<dfn attribute for=VRPositionState>orientation</dfn>
在给定的{{timeStamp}}传感器的方位,为四元数。方位偏向(沿Y轴的转角)是相对于传感器的初始偏向的,即初次读取或执行resetSensor时的值。
方位值{x: 0, y: 0, z: 0, w: 1}一般代表“向前”。
如果传感器不能提供方位数据,则返回null。
<dfn attribute for=VRPositionState>angularVelocity</dfn>
给定{{timeStamp}}时传感器的角速度。w组件值必须为0。如果传感器不能提供角速度,则返回null。
<dfn attribute for=VRPositionState>angularAcceleration</dfn>
给定{{timeStamp}}时传感器的角加速度。w组件值必须为0。如果传感器不能提供加角速度,则返回null。
## VREyeParameters
{{VREyeParameters}} 接口代表向每只眼正确渲染场景所必须的信息。
<pre class="idl">
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;
};
</pre>
### 属性 ### {#vreyeparametersattributes}
<dfn attribute for=VREyeParameters>minimumFieldOfView</dfn>
描述眼睛支持的最低视角。
<dfn attribute for=VREyeParameters>maximumFieldOfView</dfn>
描述眼睛支持的最大视角。
<dfn attribute for=VREyeParameters>recommendedFieldOfView</dfn>
描述眼睛推荐的视角。推荐设置成基于用户校准的值。
<dfn attribute for=VREyeParameters>eyeTranslation</dfn>
用户头部正中心到眼睛之间的距离,以米为单位。这个值应该就是代表该用户的瞳距(IPD),但也可以代表头盔中心点到眼球中心点的距离。左眼的值必须是负值,右眼的值必须是正值。
<dfn attribute for=VREyeParameters>currentFieldOfView</dfn>
当前眼睛的视角,就是setFieldOfView设置的值。默认为 {{recommendedFieldOfView}} 。
<dfn attribute for=VREyeParameters>renderRect</dfn>
描述在画布上渲染给眼睛的可视化内容的视口(viewport)。 左眼和右眼的{{renderRect}}必须不能有交叉, {{renderRect}}中右眼必须是左眼右边的内容。
{{renderRect}}两只眼球合起来应该是描述了HMD在采用{{currentFieldOfView}}时的最佳渲染精度,这样才能用户中心的视角维持在1:1的像素比例。
<div class="example">
很多HMD设备会将渲染的图像进行变形处理,来抵消由头盔光学元件带来的不适效果。
画布的光学分辨率经常会比HMD的物理分辨率大,来确保用户看到的最终图像效果是以1:1的比例显示在用户视角中心。
光学画布分辨率可以通过以下方式来计算:
<pre>
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);
</pre>
</div>
## VRDevice
{{VRDevice}}接口构成了支持该API的所有VR设备的基础。它包含了如设备ID和描述等一般信息。
<pre class="idl">
interface VRDevice {
readonly attribute DOMString hardwareUnitId;
readonly attribute DOMString deviceId;
readonly attribute DOMString deviceName;
};
</pre>
### 属性 ### {#vrdeviceattributes}
<dfn attribute for=VRDevice>hardwareUnitId</dfn>
各硬件单元的区分标识符,同一款物理硬件中的所有{{VRDevice}}拥有同一个{{hardwareUnitId}}值。
<dfn attribute for=VRDevice>deviceId</dfn>
区别于物理硬件设备的传感器设备的标识。这个值不会随着浏览器重启而发生变化,可用于关联保存配置数据。
<dfn attribute for=VRDevice>deviceName</dfn>
用户可读取的标识该设备的名称。
## HMDVRDevice
{{HMDVRDevice}}接口代表头盔显示器 {{VRDevice}}。它包含了该HMD的配置和其它信息。
<pre class="idl">
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);
};
</pre>
### 方法 ### {#hmdvrdevicemethods}
<dfn method for=HMDVRDevice>getEyeParameters(VREye whichEye)</dfn>
返回给定眼睛当前的{{VREyeParameters}}.
<dfn method for=HMDVRDevice>setFieldOfView(optional VRFieldOfViewInit leftFOV, optional VRFieldOfViewInit rightFOV, optional double zNear = 0.01, optional double zFar = 10000.0)</dfn>
设置两只眼睛的视角。如果都为null,或者都为0,就会启用{{recommendedFieldOfView}}所设置的值。
如果视角的值超出同一只眼{{minimumFieldOfView}} 或 {{maximumFieldOfView}}的范围,就会自动剪裁到有效范围内。
## PositionSensorVRDevice
{{PositionSensorVRDevice}}接口代表传感器{{VRDevice}}能实时报告方位数据(位置、方向可选)。
<pre class="idl">
interface PositionSensorVRDevice : VRDevice {
VRPositionState getState();
VRPositionState getImmediateState();
void resetSensor();
};
</pre>
### 方法 ### {#positionsensorvrdevicemethods}
<dfn method for=HMDVRDevice>getState()</dfn>
返回 {{VRPositionState}}的数据词典,包含当前帧(如果在requestAnimationFrame环境中)或前一帧的传感器位置状态。这个状态可以基于帧执行排期的实现机制进行预测。
VRPositionState会包含位置、方向、角度及这些值的加速度值。
可以用{{hasPosition}}和{{hasOrientation}}两个方法来检测相关成员属性是否可用;如果不可用,这些成员属性值必须为null。
<dfn method for=HMDVRDevice>getImmediateState()</dfn>
返回传感器当前瞬时状态。
<dfn method for=HMDVRDevice>resetSensor()</dfn>
重置传感器,把它当前的位置和方向朝向作为设备的原点值。
## 导航器接口扩展
<pre class="idl">
partial interface Navigator {
Promise<sequence<VRDevice>> getVRDevices();
};
</pre>
### 方法 ### {#navigatormethods}
<dfn method for=Navigator>getVRDevices()</dfn>
返回Promise,包含确定可用的{{VRDevice}}列表。应用程序应该遍历该列表,并根据{{hardwareUnitId}}访问设备所有能力。
<div class="example">
以下代码代表找出可用的第一款 {{HMDVRDevice}} 以及它相关联的 {{PositionSensorVRDevice}}(如果有的话)。
<pre>
var gHMD, gPositionSensor;
navigator.getVRDevices().then(function(devices) {
for (var i = 0; i < devices.length; ++i) {
if (devices[i] instanceof HMDVRDevice) {
gHMD = devices[i];
break;
}
}
if (gHMD) {
for (var i = 0; i < devices.length; ++i) {
if (devices[i] instanceof PositionSensorVRDevice &&
devices[i].hardwareUnitId == gHMD.hardwareUnitId)) {
gPositionSensor = devices[i];
break;
}
}
}
});
</pre>
</div>
# 致谢 # {#ack}
中文翻译:赵自明 <[email protected]>