WebXR 中的幾何體和參考空間
從根本上講,在增強現實或虛擬現實環境中用於 WebXR 演示的場景渲染是使用 WebGL 執行的,因此這兩個 API 共享許多相同的設計語言。然而,為了能夠使用 XR 頭戴裝置和其他此類裝置以真正的 3D 方式呈現場景,WebXR 還有一些必須理解的額外概念。
在本文中,我們將介紹 WebXR 如何擴充套件 WebGL 的幾何圖形,以及如何使用空間,特別是參考空間,來描述物體(包括物理物體和虛擬物體)的相對位置和方向。
文章 WebXR 中的空間跟蹤 以此處提供的資訊為基礎,涵蓋了使用者的頭部以及身體其他部位(如手)的物理位置和方向如何對映到數字世界,以及物理和虛擬物體的相對位置如何隨著它們的移動而被跟蹤,以便正確渲染和合成場景。
3D 幾何基礎
雖然我們在此將探討用於計算虛擬空間中物體的位置、方向和運動所需的數學運算,以及將場景的人類觀看者整合到其中的必要性,但對幾何學以及使用矩陣和向量管理場景 3D 表示的全面介紹遠遠超出了本文的範圍。您可以在 Web 的矩陣數學 中瞭解更多關於單個操作的資訊。
單位
在討論 WebXR 使用的 3D 空間的幾何細節之前,首先了解應用於 3D 世界的度量單位是很有用的。
長度和距離
WebGL 以米為單位測量所有距離和長度。WebXR 繼承了此標準,以及世界是一個寬兩米、高兩米、深兩米的立方體的事實。三個軸的最小值均為 -1.0,最大值為 1.0,立方體的中心位於 (0, 0, 0)。
為了您的程式碼的目的,這個八立方米的空間包含了整個宇宙。您繪製的所有內容都必須將其座標對映到此空間中,無論是在您的程式碼中明確對映,還是使用變換來調整所有頂點的座標。當然,最有效的方法是設計您的物件和程式碼以使用與 WebGL 相同的座標系。
WebGL 座標和長度在渲染時會自動轉換為渲染場景的視口大小。
角度
角度使用弧度指定。要將度數轉換為弧度,請將度數值乘以 π/180。以下程式碼片段顯示了兩個簡單的函式,degreesToRadians() 和 radiansToDegrees(),它們在兩種角度測量單位之間進行轉換。
const RADIANS_PER_DEGREE = Math.PI / 180.0;
let degreesToRadians = (deg) => deg * RADIANS_PER_DEGREE;
let radiansToDegrees = (rad) => rad / RADIANS_PER_DEGREE;
時間和持續時間
注意:出於安全原因,DOMHighResTimeStamp 通常會為時鐘引入少量不精確性,以防止其被用於指紋識別和基於時間的攻擊。
WebXR 中的所有時間和持續時間都使用 DOMHighResTimeStamp 型別測量,它是一個雙精度浮點值,指定相對於起始時間的毫秒時間。由於該值是浮點數,因此根據平臺和硬體的不同,其精度可能遠高於毫秒級別。
時間主要用於確定自場景上一幀動畫繪製以來經過的時間。因此,時間通常與顯示器的重新整理率對齊,或者如果由於效能問題需要限制幀率,則為重新整理率的一部分。這意味著,假設幀率為 60 FPS,時間通常會以 1/60 秒的間隔遞進。透過計算,我們發現這意味著每幀理想情況下將間隔 16.6667 毫秒渲染。
使用矩陣的幾何運算
我們提供了一份關於 3D 幾何相關矩陣數學的指南,包括矩陣如何在渲染 3D 場景時執行的三種主要變換中使用
請注意,當我們說變換應用於一個點時,它也(透過延伸)可以應用於一組點。由於一個物件由空間中的多個點組成的多個多邊形表示,因此將相同的變換應用於構成該物件的每個點,將把相同的變換應用於整個物件。變換也可以應用於向量,因為向量是使用座標值來定義向量的方向和大小來描述的。
關於空間的起源
一個完整的 XR 增強場景——無論是虛擬還是增強——都是由一個到幾十個參考幀的組合。場景中每個需要直接與 WebXR 系統交換位置和方向資料的物件,都必須能夠以一種可被場景中其他物件理解和適應的方式報告這些資訊。
在增強現實 (AR) 中,這是因為需要將虛擬物體插入現實世界,不僅要正確放置它們,還要確保它們不會隨著使用者視角的改變而自行漂移。在虛擬現實 (VR) 中,這一切都是為了創造一種空間感,其中使用者的動作與虛擬顯示器上呈現的影像精確匹配,以防止可能導致不適或更糟的分離和脫節。
因此,這一切都關乎創造一種空間感。從 XR 開發人員的角度來看,設計舞臺是您的使用者最關心的部分。就像建築師或佈景設計師一樣,您有能力透過物理環境創造情緒和體驗。您如何構建該空間將取決於並影響使用者如何與之互動和探索。
注意:一個空間通常具有前景、中景和背景元素。適當的平衡可以創造獨特的臨場感並引導您的使用者。前景包括您可以直接互動的物件和介面。中景包括您可以在一定程度上互動的物件,或者可以接近以更仔細地檢查和參與的物件。另一方面,背景通常在很大程度上或完全是非互動的,至少在使用者能夠接近它並將其帶入中景或前景範圍之前如此。
在 WebXR 中,空間的基本概念——即場景發生的座標空間——由 XRSpace 例項表示。空間用於確定使用者環境中物體和其他實體(如光源和攝像機)的相對位置和運動。
如前所述,任何給定的 3D 點都由三個分量組成,每個分量標識距空間中心沿三個軸之一的距離。
這是空間原生原點,對應於使用者環境中的特定物理位置。每個空間都有自己的原生原點,由 XR 裝置的跟蹤系統跟蹤。這可能與有效原點不同,有效原點是空間區域性座標系的原點。
座標系的方向性如下圖所示
一個名為原點偏移的 XRRigidTransform 用於將點從空間自身的有效座標系轉換到 XR 裝置的原生座標系。原點偏移最初是一個單位變換,因為通常在首次建立空間時,兩個原點是對齊的。然而,隨著對齊變化隨時間積累,原點偏移可能會改變以進行補償。
空間中點相對於原點的位置由其沿上圖中所示的三個空間軸的距離確定。空間原點是點 (0, 0, 0),位於空間的中心和沿每個軸的零位置。具體來說,在初始啟動條件下,在檢視器對空間的預設方向下
- X 軸水平向右延伸,遠離原點,x 座標為 +1.0 位於世界的右邊緣。x 的負值從原點向左延伸,在空間的左邊緣達到 -1.0。
- Y 軸正向從原點向上延伸到螢幕頂部,在世界空間的頂部達到 +1.0。y 值小於 0 的位於原點下方,向下延伸到螢幕底部,在世界空間的底部達到 -1.0。
- Z 軸從原點向螢幕外延伸,在該方向上離使用者最近的點達到 +1.0。z 的負值從使用者向螢幕深處延伸,世界中最遠的點 z 為 -1.0。
在最簡單的層面上,每個物件都是由 3D 空間中的點和偏移變換定義的一組多邊形,指示如何移動和旋轉物件以將其定位到空間中所需的位置。如果偏移變換是單位矩陣,則物件位於原點。
然而,為了對空間跟蹤和場景幾何有用,您需要能夠將 XR 裝置感知到的位置與空間的座標系關聯起來。這就是參考空間的作用。
參考空間
由於可用的 XR 硬體種類繁多,來自許多開發者的各種外形尺寸,期望開發者必須直接與所使用的跟蹤技術通訊是不切實際且不可擴充套件的。相反,WebXR Device API 的設計是為了讓開發者規劃使用者的體驗並請求最能代表這些需求的適當參考空間。這是透過向使用者代理請求匹配這些需求的 XRReferenceSpace 來完成的。
XRReferenceSpace 物件充當將一個座標系參考幀調整到另一個座標系參考幀的手段。戴上頭顯後,假設您周圍的虛擬世界有一個座標系,其中您的位置是 (0, 0, 0)——也就是說,您處於一切的中心。這難道不令人感到振奮嗎?前方,直接在您的頭顯前面,是 -Z 軸,+Z 在您身後。X 軸正向在您的右側,負向在您的左側。Y 軸在您向下移動時為負,在您向上移動時為正。這表示在您開始使用 XR 系統時頭顯在空間中的位置,原點 (0, 0, 0) 大致位於您的鼻樑處。這個空間是世界空間。
接下來,考慮您左手中的 XR 控制器。它能夠報告移動和方向,但它對頭戴裝置的位置或更重要的是其座標系一無所知。但控制器仍然需要一種方式向您的應用程式報告其位置。因此,它有自己的座標系。當輸入事件發生時,這個參考空間會提供給您的應用程式。這個參考空間內部知道如何將控制器的座標對映到頭戴裝置的座標,因此 WebXR 可以為您來回轉換座標。
一旦建立,XRReferenceSpace 就保證了一定程度的運動和方向跟蹤支援,並提供了一種獲取 XRViewerPose 的機制,從中您可以獲得一個矩陣,該矩陣表示該空間相對於世界空間的位置和朝向方向,如果該空間代表一個觀察者(例如使用者的頭戴裝置、觀察者的頭戴裝置或虛擬攝像機)。
所有這些都是瀏覽器的責任,它提供一致的行為,無論底層參考空間的能力如何。無論單個 XR 裝置多麼強大或簡單,使用 WebXR 編寫的程式碼仍然可以在可用硬體的限制下工作。
無論您選擇哪種參考空間型別,其型別都是 XRReferenceSpace 或派生自 XRReferenceSpace 的型別。當前可用的參考空間型別如下所示。
有界地板-
一個
XRBoundedReferenceSpace,類似於local型別,但使用者預計不會超出由返回物件中的boundsGeometry給出的預定邊界。 local-
一個
XRReferenceSpace跟蹤空間,其原生原點位於會話建立時觀看者位置附近。確切位置取決於底層平臺和實現。使用者預計不會超出其起始位置移動太多,跟蹤針對此用例進行了最佳化。對於具有六個自由度 (6DoF) 跟蹤的裝置,local參考空間嘗試使原點相對於環境保持穩定。 區域性地板-
一個
XRReferenceSpace,類似於local型別,只是起始位置被放置在檢視器可以站立的安全位置,其中 Y 軸的值在地面高度為 0。如果地面高度未知,則使用者代理將估算地面高度。如果估算的地面高度不為零,瀏覽器應將其四捨五入以避免指紋識別(可能四捨五入到最近的釐米)。 無界-
一個
XRReferenceSpace跟蹤空間,允許使用者完全自由移動,可能在距離其原點極遠的距離上移動。檢視器根本不被跟蹤;跟蹤針對使用者當前位置周圍的穩定性進行了最佳化,因此原生原點可能根據需要漂移以適應這一需求。 檢視器-
一個
XRReferenceSpace跟蹤空間,其原生原點跟蹤觀看者的位置和方向。這用於使用者可以物理移動的環境,並且所有XRSession例項都支援它,包括沉浸式和內聯式,儘管它對內聯式會話最有用。它在確定觀看者和輸入之間的距離,或在處理偏移空間時特別有用。否則,通常會更頻繁地使用其他參考空間型別之一。
本指南的其餘部分將探討如何為您的應用程式需求選擇正確的參考空間。
使用參考空間定義空間關係
有許多常用的方法來參考物體相對於其環境的位置和方向,以及約束環境本身。為此,WebXR 定義了一組標準空間,稱為參考空間,每個空間都支援不同的技術,用於將其區域性空間的參考幀座標系與其所在空間的座標系相關聯。
但是,無論使用哪種型別的參考空間,您都可以使用相同的函式將座標從一個空間轉換到父空間。
選擇參考空間型別
首先,讓我們陳述決定使用哪種參考型別過程中最簡單的一步:您最可能使用的參考空間是 local、local-floor、unbounded 或 bounded-floor。
地板級別參考空間
名稱中帶有 -floor 的參考空間型別的工作方式與相應的非地板空間相同,只是它們嘗試自動確保檢視器位於地面水平或附近(但始終高於地面)的安全位置。這是 y 座標始終為 0 的平面,除非另行建立地板。如果房間的地板不平坦或地板高度高於地面水平不同,這些空間型別則不可行,因為它們不支援化身垂直位置的變化。
主要參考空間型別
viewer 參考空間對應於檢視器在空間中的位置;它由 XRFrame 方法 getViewerPose() 返回的 XRViewerPose 使用。通常情況下,它不會直接用於其他用途。唯一的真正例外是,當您在網頁內容中內聯執行 XR 場景時,您很可能會使用 viewer 參考空間。
local 參考空間通常用於描述一個相對較小的區域,例如單個房間。它不僅在使用沉浸式會話模式(immersive-vr 或 immersive-ar)時始終可用,而且在請求新會話時始終包含在可選功能中;因此,透過 navigator.xr.requestSession() 建立的每個會話都支援 local 參考空間型別。
要表示一個大面積區域——可能涉及多個房間或更遠——您可以使用 unbounded 參考空間型別,它不對觀看者的移動施加任何限制。如果您希望阻止使用者進入某些區域,則必須自行處理。
bounded-floor 參考空間型別沒有對應的非地板邊界型別。如果使用者的 XR 硬體允許他們在現實世界空間中移動,並且您能夠這樣做,那麼使用 bounded-floor 參考空間可能會很有用,它允許您明確定義允許和安全的通行區域的邊界。有關有界參考空間使用的更多資訊,請參閱文章 使用有界參考空間。
透過使用參考空間來描述物體的位置和方向,WebXR 能夠標準化您用於描述這些資料的資料形式,無論底層 XR 硬體如何。然後,參考空間的配置能夠為您提供正確渲染空間內容所需的檢視矩陣和物件姿態。
建立參考空間
最頂層的空間——透過呼叫 XRSession 方法 requestReferenceSpace() 獲得的空間——描述了用於整個世界空間的座標系。一切都與這個座標系基本相關,它代表了使用者裝置位置與虛擬世界之間的關係。
雖然您可以將 WebXR 用於從世界增強註釋到 360° 影片播放,再到科學模擬,再到虛擬現實訓練系統,或者任何您可以想象到的其他事物,但讓我們以 3D 影片遊戲為例,作為典型的 WebXR 應用程式。考慮玩家角色站在遊戲世界空間中的模型。您使用世界參考空間定義的座標系來定位該角色。
要將玩家移動到新位置,您可以重寫所有座標,或者每次移動時手動應用變換,但有一個更簡單的方法,這要歸功於參考空間及其彼此相對建立的能力。建立一個 XRRigidTransform 物件,表示玩家角色的新位置和方向,然後使用 XRReferenceSpace 方法 getOffsetReferenceSpace() 建立一個新的參考空間來表示角色在新位置的視角。這在實現支援使用鍵盤或滑鼠等非 XR 裝置來移動玩家角色時特別方便。
有了新建立的參考空間,角色可以保持在相同的座標處,但在世界中看起來位於新位置(並從新位置的角度看世界)。有關如何使用參考空間管理玩家視角的更詳細資訊,請參閱文章
在我們的遊戲頭像示例中,頭像(或任何其他移動的生物或機器)很少是簡單地在世界中滑動的塊狀物。它們通常具有額外的形狀以及內部運動,例如移動的腿、走路時擺動的手臂、轉動或晃動的頭部、四處移動的武器等等。使用標準的 WebGL 技術和定位矩陣或 XRRigidTransform 來將這些物件移動到相對於有效原點的正確位置,從而使它們栩栩如生。
參考空間裝置限制
某些 XR 裝置無法支援給定體驗,儘管 API 努力彌補任何缺失的功能。例如,對於像 GearVR 裝置這樣的基本頭戴裝置,無法使其在需要支援使用者透過跟蹤其真實世界運動來在環境中行走的應用中工作。
為了支援漸進增強——從而擴大您的應用程式或站點的可用性——您應該選擇提供最低所需功能的參考空間,或者提供一種回退機制,檢測獲取參考空間失敗的嘗試,並嘗試使用功能較弱的替代方案。
出現的相容性問題可能非常基礎,例如在僅支援 VR 的頭戴裝置上無法支援 immersive-ar 模式(增強現實會話),或者可能涉及請求一個或多個在嘗試建立 XR 會話時無法滿足的必需選項。
XR 會話是使用 navigator.xr.requestSession() 方法建立的。它的一個可選引數是一個物件,您可以使用它來指定會話必須(或理想情況下應)支援的必需和/或可選功能。目前,唯一支援的選項是標識標準參考空間的字串。透過使用這些,您甚至可以在程式碼執行之前確保您可以訪問支援您所需或首選參考空間型別的 WebXR 會話。
注意:目前,要使用或首選的參考空間是建立 XRSession 時唯一可用的選項。未來,可能會有更多選項可用。
定位和定向物體
應用程式和 WebXR API 之間交換的所有空間(位置、方向和運動)資訊都與幀渲染時的一個特定空間相關。任何進一步的位置和方向管理都在您和 WebGL 之間,儘管您確實使用了參考空間的原點偏移,以便在 3D 世界中正確放置物件。
當需要渲染動畫幀時,呼叫 WebXR 會話的 XRSession 物件的 requestAnimationFrame() 方法時指定的 callback 函式會被呼叫。callback 函式會接收一個引數,指示幀發生的時間,並且應該執行相應動畫幀的所有渲染。
隨著 callback 函式以遞增的時間值重複呼叫,callback 函式生成一系列幀,這些幀使用 XR 硬體呈現,從而向用戶顯示 3D 場景。
您可以在文章 渲染和 WebXR 幀動畫回撥 中瞭解更多關於動畫過程的資訊。
有關在虛擬空間中定位、定向和移動物件的示例以及更詳細的程式碼級解釋,請參閱文章 移動、方向和運動。