WebXR 開發者的視角回顧

由於 WebXR 使用 WebGL 來渲染構成透過 XR 硬體顯示的 3D 環境的檢視,因此很容易認為視角相關的問題與任何 WebGL 專案中的問題相同。這在很大程度上是正確的,但有幾個特定的主題需要重新審視,並且需要考慮一些小的附加指南,以確保您的應用程式看起來正確,更重要的是,您的 3D 世界不會因為眩暈或其他效果導致人們生病,這些效果會在所見內容與大腦預期現實不符時發生。

在本文中,我們將探討您的專案計算、應用和思考視角的方式可能與為非 XR 應用程式編寫的程式碼不同的場景。

視錐體的困擾

每個 WebXR 會話(由 XRSession 物件表示)都提供一組可以透過建立新的 XRRenderState 物件來配置的選項,並透過呼叫會話的 updateRenderState() 方法來啟用更新後的狀態,以替換當前配置。

這些值中的大多數定義了 XR 裝置的 視錐體;也就是說,應該渲染的裝置視野的子集。視錐體可以使用四個關鍵資料點來表示:視場角、渲染影像的 縱橫比,以及近剪切平面和遠剪切平面的距離。

歡迎來到投影矩陣

大多數情況下,您將使用的投影模型是透視投影模型,因此其投影矩陣稱為透視投影矩陣。此矩陣用於將 3D 虛擬世界中的每個畫素對映到正在渲染的檢視的 2D 後臺緩衝區中的一個點。

在典型情況下,您可以並且應該直接從您正在渲染的檢視中獲取透視投影矩陣。 XRView 物件的 projectionMatrix 屬性包含表示檢視透視的投影矩陣,並且幾乎應該始終按原樣使用。對 XRView 提供的投影矩陣所做的更改很可能導致渲染內容相對於現實世界的風景出現失真或對齊不佳;這可能足夠嚴重,至少會導致您的某些使用者出現 虛擬現實疾病

例如,如果您的應用程式使用名為 uProjectionMatrix 的 WebGL uniform 將投影矩陣傳遞給您的著色器,您可以使用類似以下的程式碼來傳遞當前正在渲染的檢視的投影矩陣

js
gl.uniformMatrix4fv(uProjectionMatrix, false, view.projectionMatrix);

自定義投影矩陣

雖然通常應避免手動構建或修改檢視提供的投影矩陣,但在某些情況下可以這樣做。最常見的原因可能是為了出於效能原因更改近剪切平面和遠剪切平面的距離,以增加或減少要渲染的多邊形數量。當遊戲提供調整觀看距離的首選項時,就是透過更改這些平面距離值來實現的。

在沉浸式模式下,WebXR 系統從硬體供應商提供的軟體中獲取預設的 視錐體。此視錐體基於裝置的鏡頭、顯示硬體和攝像頭的某種組合。從影像感測器的尺寸到鏡頭的焦距,一切都參與了此計算。

沉浸式體驗使用硬體定義的視場、焦距等,因此在使用沉浸式會話時,您只能更改近剪下距離和遠剪下距離。這是透過設定 XRRenderState 屬性 depthNeardepthFar 的值來完成的。

在內聯模式下,您還可以透過設定 renderStateinlineVerticalFieldOfView 屬性的值來直接更改視場。對於任何沉浸式會話,此屬性需要設定為 null

一旦有了視錐體,您就可以使用像下面這樣的函式來計算 WebGL 在渲染場景時使用的投影矩陣

js
function makePerspectiveMatrix(fieldOfViewInRadians, aspectRatio, near, far) {
  const f = 1.0 / Math.tan(fieldOfViewInRadians / 2);
  const rangeInv = 1 / (near - far);

  return [
    f / aspectRatio,
    0,
    0,
    0,
    0,
    f,
    0,
    0,
    0,
    0,
    (near + far) * rangeInv,
    -1,
    0,
    0,
    near * far * rangeInv * 2,
    0,
  ];
}

nearfar 的值直接從視錐體獲得;它們分別是原點到近剪切平面和遠剪切平面上最近點的距離。縱橫比是透過將視場寬度除以其高度獲得的值。如果目標顯示器使用 16:9 的縱橫比,則用於 aspectRatio 的值應為 16/9,即 1.7777777778。

如果您使用的是提供矩陣數學函式的庫或框架,它幾乎肯定會有一個類似的函式。例如,在流行的 glMatrix 庫中,您會在函式 mat4.perspective() 中找到它。

無論它來自哪裡,一旦您獲得了投影矩陣,就可以在使用 WebGL 渲染場景時使用它。

與現實保持一致

在增強現實 (AR) 應用程式中,您渲染的內容會疊加在現實世界之上。要做到這一點,您的視角計算需要與觀看者對周圍世界的視角相匹配。否則,您的物件將無法正確地與現實對齊。

如果您的虛擬攝像頭的透視投影矩陣不能使虛擬物件具有與現實世界相同的視觀效果,那麼虛擬世界和物理世界之間的差異可能會令人不適,甚至更糟的是,會在您的應用程式使用者中引起眩暈、暈動症或其他形式的不適。

一個相關的問題是,如果您使用透視矩陣來確定物件的位置,那麼您的透視投影矩陣與使用者對世界的物理視角之間的不匹配可能導致物件放置不準確。例如,如果您的應用程式允許使用者在牆上掛虛擬畫作,但透視矩陣不匹配,那麼放置的畫作可能實際上不會貼在牆上,會部分與牆體相交,或者一端比另一端更靠近牆壁,而不是與牆壁平行。

另見