XRView - 表示特定帧在 XR 场景中的单个视图
XRView
是 WebXR 设备 API 的接口,表示特定帧在 XR 场景中的单个视图,并提供视点的方向和位置信息。你可以把它看作是表示特定的眼睛或相机,以及它是如何观看世界的。3D 框架将包含两个视图,每只眼睛一个视图,并以适当的距离隔开,该距离近似于观看者眼睛之间的距离。这样,当将两个视图单独投影到适当的眼睛中时,它们就可以模拟 3D 世界。
属性
eye
只读
表示透视图的两只眼睛(left
或 right
)中的哪只。使用此值可确保正确渲染或呈现要呈现给特定眼睛的任何内容。如果值为 none
表示单一数据(例如 2D 图像,全屏文本视图或不需要 3D 图像的特写视图)。
projectionMatrix
只读
给定 eye
指示的视点,将转换场景以正确显示的投影矩阵。该矩阵应直接使用,以避免可能导致严重的用户不适感的显示失真。
transform
只读
一个 XRRigidTransform
,它描述在渲染的 XRFrame
上调用 getViewerPose()
时指定的视点相对于 XRReferenceSpace
的视点的当前位置和方向。
使用注意
XRView
的位置和数量
每帧 渲染场景时,通过调用 XRFrame
对象的 XRFrame.getViewerPose
方法获取 XRViewerPose
(本质上表示查看者头部的位置), 可以获得用于当前场景的场景渲染的视图集。该对象的 views
属性是表示视点的所有 XRView
对象的列表,这些视点可用于构造场景以呈现给用户。
可能会有 XRView
对象,它们表示重叠的区域以及完全不同的区域。在游戏中,例如,你可以使用安全摄像头或其他设备来观察一个远程站点。换句话说,不要假设给定查看器上有两个视图。可能只有一个(例如,以 inline
模式渲染场景时),也有可能是多个(尤其是在视野很大的情况下)。也可能有代表观察者观看动作的视图,或者没有其他观点与玩家的眼睛有关的直觉。也可能存在代表观察者观看动作的视图,或者其他与玩家的眼睛没有直接关联的观察点。
此外,根据时间的需要,视图数量可以随时更改。因此,您应该每次都处理视图列表,而无需基于先前的帧进行假设。
给定 XRViewerPose
在视图中的所有位置和方向都在传递给 XRFrame.getViewerPose()
的参考空间中指定;这称为查看者参考空间。transform
属性描述在该参考空间中给定的 XRView
所代表的眼睛或相机的位置和方向。
目标渲染层
要渲染框架,只需迭代 XRViewerPose
视图,将每个视图渲染到框架 XRWebGLLayer
内的适当视口中。当前,规范(以及 WebXR 的所有当前实现)是围绕着将每个 XRView
渲染到单个 XRWebGLLayer
中而设计的,然后将其呈现在 XR 设备上,其中一半用于左眼,另一半用于右眼。XRViewport
用于每个视图定位渲染到正确的一半的层。每个视图的 XRViewport
用于将渲染放置到图层的一半。
如果将来每个视图都可以呈现到不同的层中,则必须对 API 进行更改,因此现在可以假定所有视图都可以呈现到同一层中。
实例
准备渲染每个视图的姿势
要绘制用户看到的每一帧的所有内容,需要遍历 XRViewerPose
对象的 views
列表返回的视图列表:
for (let view of pose.views) {
let viewport = glLayer.getViewport(view);
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
// 绘制场景;被绘制的眼睛由 view.eye 标识。
}
特殊视图转换
在渲染和照明场景时,在视图上使用了一些特殊的变换。
模型视图矩阵
模型视图矩阵是一个定义对象相对于其所在空间的位置的矩阵:如果 objectMatrix
是应用于对象以提供其基本位置和旋转的变换,则模型视图可以通过将对象的矩阵乘以视图变换矩阵的逆来计算矩阵,如下所示:
mat4.multiply(modelViewMatrix, view.transform.inverse.matrix, objectMatrix);
正规矩阵
在照亮场景时,将使用模型视图的正规矩阵,以变换每个表面的法线向量,以确保在给定表面相对于一个或多个光源的方向和位置的情况下,光以正确的方向反射。它是通过反转然后转置模型视图矩阵来计算的:
mat4.invert(normalMatrix, modelViewMatrix);
mat4.transpose(normalMatrix, normalMatrix);
传送物体
要以编程方式移动和 / 或旋转(通常称为 “传送(teleporting)”)对象,您需要为该对象创建一个新的参考空间,该参考空间将应用封装所需更改的变换。createTeleportTransform()
函数返回将对象移动和旋转所需的变换,该对象的当前情况由参考空间 refSpace
描述到新的位置和方向,该位置和方向使用先前记录的产生偏移量的鼠标和键盘输入数据进行计算沿所有三个轴的偏航,俯仰和位置。
function applyMouseMovement(refSpace) {
if (!mouseYaw && !mousePitch && !axialDistance &&
!transverseDistance && !verticalDistance) {
return refSpace;
}
// 根据俯仰和偏航计算用于旋转图像的四元数。
quat.identity(inverseOrientation);
quat.rotateX(inverseOrientation, inverseOrientation, -mousePitch);
quat.rotateY(inverseOrientation, inverseOrientation, -mouseYaw);
// 计算对象的真实 “向上” 向量。
vec3.cross(vecX, vecY, cubeOrientation);
vec3.cross(vecY, cubeOrientation, vecX);
// 现在,计算将对象传送到指定点的变换,并保存它的副本以供以后显示给用户;
// 否则,我们可能不需要保存 mouseMatrix。
let newTransform = new XRRigidTransform({x: transverseDistance,
y: verticalDistance,
z: axialDistance},
{x: inverseOrientation[0], y: inverseOrientation[1],
z: inverseOrientation[2], w: inverseOrientation[3]});
mat4.copy(mouseMatrix, newTransform.matrix);
// 创建一个新的参考空间,该空间会将对象转换为新的位置和方向,并返回新的参考空间。
return refSpace.getOffsetReferenceSpace(newTransform);
}
此代码分为四个部分。首先,计算四元数 inverseOrientation
。给定 mousePitch
(围绕对象参考空间的 X 轴的旋转)和 mouseYaw
(围绕对象的 Y 轴的旋转)的值,它表示对象的旋转。
第二部分计算对象的 “向上” 向量。该矢量指示整个场景中但在对象的参考空间中 “向上” 的方向。
第三部分创建新的 XRRigidTransform
,指定一个点,该点提供沿三个轴的偏移量作为第一个参数,方向四元数作为第二个参数。返回的对象的 matrix
属性是将点从场景的参考空间转换为对象的新位置的实际矩阵。
最后,创建一个新的参考空间来完整描述两个参考空间之间的关系。该参考空间将返回给调用方。
要使用此功能,我们将根据您的需要将返回的参考空间传递到 XRFrame.getPose()
或 getViewerPose()
中。然后,返回的 XRPose
将用于实际渲染当前帧的场景。
您可以在我们的文章运动,方向和运动中找到更和完整的实例。
规范
规范 | 状态 | 备注 |
---|---|---|
WebXR Device API XRView 的定义 |
工作草案 | 初始定义。 |
桌面浏览器兼容性
特性 | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
基础支持 | 79 | 79 | 不支持 | 不支持 | 不支持 | 不支持 |
eye | 79 | 79 | 不支持 | 不支持 | 不支持 | 不支持 |
projectionMatrix | 79 | 79 | 不支持 | 不支持 | 不支持 | 不支持 |
transform | 79 | 79 | 不支持 | 不支持 | 不支持 | 不支持 |
移动浏览器兼容性
特性 | Android | Chrome for Android | Edge mobile | Firefox for Android | IE mobile | Opera Android | iOS Safari |
---|---|---|---|---|---|---|---|
基础支持 | 不支持 | 79 | 未知 | 不支持 | 未知 | 不支持 | 不支持 |
eye | 不支持 | 79 | 未知 | 不支持 | 未知 | 不支持 | 不支持 |
projectionMatrix | 不支持 | 79 | 未知 | 不支持 | 未知 | 不支持 | 不支持 |
transform | 不支持 | 79 | 未知 | 不支持 | 未知 | 不支持 | 不支持 |