XRView

可用性有限

此特性不是基線特性,因為它在一些最廣泛使用的瀏覽器中不起作用。

安全上下文: 此功能僅在安全上下文(HTTPS)中可用,且支援此功能的瀏覽器數量有限。

實驗性: 這是一項實驗性技術
在生產中使用此技術之前,請仔細檢查瀏覽器相容性表格

WebXR Device APIXRView 介面描述了特定幀的 XR 場景的單個檢視,提供了視點的方向和位置資訊。你可以將其理解為描述一隻眼睛或一個攝像機如何觀察世界的描述。一個 3D 幀會包含兩個檢視,分別對應於兩隻眼睛,它們之間有適當的距離,以近似觀察者眼睛之間的距離。這樣,當這兩個檢視分別投射到對應的眼睛時,就可以模擬出 3D 世界。

例項屬性

eye 只讀 實驗性

XRView 所代表的視角是兩隻眼睛中的哪一隻(left)或(right)。此值用於確保任何預先渲染的、用於呈現給特定眼睛的內容都能被正確分發或定位。當 XRView 呈現單檢視資料時(例如 2D 影像、文字的全屏檢視,或不需要以 3D 形式顯示的近距離檢視),該值也可以是 none

isFirstPersonObserver 只讀 實驗性

返回一個布林值,指示 XRView 是否為第一人稱觀察者檢視。

projectionMatrix 只讀 實驗性

投影矩陣,用於根據 eye 指示的視角正確地轉換場景。應直接使用此矩陣,以避免可能導致使用者嚴重不適的演示失真。

recommendedViewportScale 只讀 實驗性

如果你希望使用者代理(user agent)設定此視口的推薦視口比例,你可以使用 `requestViewportScale()`;否則返回 null

transform 只讀 實驗性

一個 XRRigidTransform 物件,描述了當前視點相對於在渲染的 XRFrame 上呼叫 getViewerPose() 時指定的 XRReferenceSpace 的位置和方向。

例項方法

requestViewportScale() 只讀 實驗性

請求使用者代理將此視口的請求視口比例設定為請求的值。

用法說明

每幀的 XRView 位置和數量

在渲染場景時,用於渲染當前幀觀察者場景的檢視集合是透過呼叫 XRFrame 物件的 getViewerPose() 方法來獲取的,該方法返回表示(本質上)觀察者頭部位置的 XRViewerPose。該物件的 views 屬性是一個 XRView 物件列表,代表可以用來構建場景並呈現給使用者的視點。

XRView 物件可能代表重疊區域,也可能代表完全不同的區域;例如,在遊戲中,你可能會有可以呈現出來以觀察遠端站點(透過安全攝像頭或其他裝置)的檢視。換句話說,不要假設一個給定的觀察者只有兩個檢視;可能只有一種(例如,在 inline 模式下渲染場景時),也可能有很多(尤其是在視場非常大的情況下)。也可能存在代表觀察正在發生事件的觀察者,或其他不直接與玩家眼睛相關的視點。

此外,檢視的數量可以隨時更改,具體取決於當時的需要。因此,你應該每次都處理檢視列表,而不應基於之前幀做出假設。

給定 XRViewerPose 的所有檢視中的所有位置和方向,都是在傳遞給 XRFrame.getViewerPose() 的參考空間中指定的;這被稱為觀察者參考空間transform 屬性描述了由 XRView 表示的眼睛或攝像機在該參考空間中的位置和方向。

目標渲染層

要渲染一幀,你需要遍歷 XRViewerPose 的檢視,並將每個檢視渲染到該幀 XRWebGLLayer 中的相應視口。目前,規範(因此所有當前的 WebXR 實現)都是圍繞將每個 XRView 渲染到單個 XRWebGLLayer 來設計的,然後該層會呈現到 XR 裝置上,其中一半用於左眼,一半用於右眼。每個檢視的 XRViewport 用於將渲染定位到圖層的正確一半。

如果將來每個檢視都可以渲染到不同的圖層,那麼 API 將需要進行修改,因此目前可以安全地假設所有檢視都將渲染到同一個圖層。

示例

準備渲染姿勢的每個檢視

要繪製使用者看到的所有內容,每一幀都需要遍歷 XRViewerPose 物件 views 列表返回的檢視列表。

js
for (const view of pose.views) {
  const viewport = glLayer.getViewport(view);

  gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

  // Draw the scene; the eye being drawn is identified
  // by view.eye.
}

特殊檢視變換

在渲染和光照場景時,有幾個特殊的變換會應用於檢視。

模型檢視矩陣

模型檢視矩陣是一個矩陣,它定義了一個物件相對於其所在空間的位置:如果 objectMatrix 是應用於物件的變換,用於提供其基本位置和旋轉,那麼模型檢視矩陣可以透過將物件的矩陣乘以檢視變換矩陣的逆來計算,如下所示:

js
mat4.multiply(modelViewMatrix, view.transform.inverse.matrix, objectMatrix);

法線矩陣

模型檢視的法線矩陣用於在光照場景時,透過變換每個表面的法向量,以確保光線能夠朝著正確的方向反射,這取決於表面相對於光源的方向和位置。它是透過反轉然後轉置模型檢視矩陣來計算的。

js
mat4.invert(normalMatrix, modelViewMatrix);
mat4.transpose(normalMatrix, normalMatrix);

傳送物件

要以程式設計方式移動和/或旋轉(通常稱為傳送)一個物件,你需要為該物件建立一個新的參考空間,該空間應用一個封裝了所需更改的變換。 `createTeleportTransform()` 函式返回了將物件從當前情況(由參考空間 `refSpace` 描述)移動和旋轉到新位置和方向所需的變換。這個新位置和方向是透過先前記錄的滑鼠和鍵盤輸入資料計算得出的,這些資料生成了偏航(yaw)、俯仰(pitch)以及沿三個軸的位置偏移。

js
function applyMouseMovement(refSpace) {
  if (
    !mouseYaw &&
    !mousePitch &&
    !axialDistance &&
    !transverseDistance &&
    !verticalDistance
  ) {
    return refSpace;
  }

  // Compute the quaternion used to rotate the image based
  // on the pitch and yaw.

  quat.identity(inverseOrientation);
  quat.rotateX(inverseOrientation, inverseOrientation, -mousePitch);
  quat.rotateY(inverseOrientation, inverseOrientation, -mouseYaw);

  // Compute the true "up" vector for our object.

  vec3.cross(vecX, vecY, cubeOrientation);
  vec3.cross(vecY, cubeOrientation, vecX);

  // Now compute the transform that teleports the object to the
  // specified point and save a copy of it to display to the user
  // later; otherwise we probably wouldn't need to save mouseMatrix
  // at all.

  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);

  // Create a new reference space that transforms the object to the new
  // position and orientation, returning the new reference space.

  return refSpace.getOffsetReferenceSpace(newTransform);
}

這段程式碼分為四個部分。在第一部分,計算四元數 `inverseOrientation`。它表示基於 `mousePitch`(繞物件參考空間的 X 軸旋轉)和 `mouseYaw`(繞物件 Y 軸旋轉)的值的物件旋轉。

第二部分計算物件的“向上”向量。這個向量指示了在整個場景中“向上”的方向,但在物件的參考空間中。

第三部分建立新的 XRRigidTransform,指定一個提供沿三個軸偏移的點作為第一個引數,並指定方向四元數作為第二個引數。返回物件的 matrix 屬性是將點從場景參考空間轉換到物件新位置的實際矩陣。

最後,建立一個新的參考空間來完全描述兩個參考空間之間的關係。該參考空間會返回給呼叫者。

要使用此函式,我們將返回的參考空間傳遞給 XRFrame.getPose()getViewerPose(),具體取決於你的需求。返回的 XRPose 將隨後用於渲染當前幀的場景。

你可以在我們的文章 移動、方向和運動 中找到更廣泛、更完整的示例。

規範

規範
WebXR Device API
# xrview-interface

瀏覽器相容性