iT邦幫忙

2025 iThome 鐵人賽

DAY 21
0
Modern Web

WebXR未來新視界:Babylon.js打造Web的VR/AR/XR體驗系列 第 21

[Day21] Babylon.js WebXR 攝影機和控制器

  • 分享至 

  • xImage
  •  

Babylon.js WebXR攝影機

const xrCamera = new WebXRCamera("nameOfCamera", scene, xrSessionManager);

WebXR Camera是專為VR/AR體驗設計的攝影機,所以只要是XR攝影機基本上就是選這款。
它本質上是FreeCamera的擴展,但增加了處理XR數據和雙眼渲染的能力。
比較個別的是WebXR Camera不接受初始位置,WebXR攝影機的位置是根據裝置的當前位置相對於參考空間計算出來的。攝影機的位置會在 第一個XRFrame渲染時,被來自XR裝置的數據自動填入。也會根據XRFrame持續發送裝置大概位置的訊息並逐幀更新裝置攝影機的位置。

當進行WebXR傳送移動的時候並非直接移動攝影機的位置,而是根據傳送前後的位置變化,計算出一個新的參考空間再做計算。

在使用XR攝影機的時候可以透過取得使用者身高(從地板量起),來進行更準確的操作,但要注意這個身高回傳的值,會依據參考空間類型而有所不同,如果是local-floor就會提供使用者的身高;當是viewer 的話就會是設定上的高度:

const userHeight = xrCamera.realWorldHeight;

控制器與互動

WebXR的一大進步在於能夠支援多樣化的輸入設備,包括動作控制器、觸控螢幕,甚至是手部追蹤。Babylon.js 支援 WebXR的Input Profiles repositoryInput Profiles repository是一個由 W3C 社群推動的開源資料庫,裡面包含了幾乎所有市面上 XR 控制器(如 Oculus Touch、Valve Index、HTC Vive 等)的標準化定義3D 模型。因此可以實現自動下載並加載與硬體相符的 3D 控制器模型。開發者只需要訂閱 onMeshLoadedObservable 來確認模型是否準備好就可以使用了,或是訂閱onMotionControllerInitObservable 來確認控制器的初始化或載入好沒有。而開發者則可以專注在邏輯上的開發。

在WexXR,使用者輸入的來源有三種

  1. tracked-pointer :控制器手把輸入
  2. screen :觸控螢幕輸入
  3. gaze :基於凝視的輸入

而Babylon 的WebXRInput會自動處理它們,他會偵測和管理所有XR控制器的連線和斷開,每個連接的輸入源都會自動建立一個WebXRInputSource負責連接控制器和連接組件並載入模型。

我們只要放心地知道他會自動處理這塊,就能把精力放在邏輯開發,並透過它的Observable onControllerAddedObservableonControllerRemovedObservable 來啟動和結束就好了。

onControllerAddedObservable : 當偵測到新的輸入來源並建立其對應的WebXRInputSource時觸發

onControllerRemovedObservable : 當控制器離開體驗時,在其WebXRInputSource實例被處理之前觸發。

另外每個輸入源都有兩個特別的參考空間,用於定義不同的互動行為:

空間名稱 目的 程式碼
targetRay 瞄準與點擊。 代表雷射線、手指尖或注視點的方向。 xrInputSource.getWorldPointerRayToRef(pointerRay)
gripSpace 抓取與定位。 代表控制器手柄底座或手掌的中心位置。 xrInputSource.getWorldPointerRayToRef(gripRay, true)

控制器的元件

由於各大廠家的XR裝置會有不同定義的主要元件,可以透過下方這段取得主要元件。

const mainComponent = motionController.getMainComponent();

常見的有Trigger(板機)、Squeeze(握持)、Thumbstick(搖桿)、Touchpad(觸摸板)和 Button(按鈕)。元件會逐幀更新,常見會有不同狀態如touchedpressedaxes (一個從 0 到 1 的值,0 表示完全未按下,1 表示完全按下)。可以透過 IDType 來獲取元件,它具有唯一的元件 ID,與實際硬體相對應。若要取得可用元件的列表,可以使用getComponentIds 會傳回一個包含所有ID的字串array:

const ids = motionController.getComponentIds();
// ids = ["a-button", "b-button", "xr-standard-trigger", .....]

// 透過 ID 獲取扳機
const triggerComponent = motionController.getComponent("xr-standard-trigger"); 

// 獲取所有按鈕類型的元件
const buttonComponents = motionController.getAllComponentsOfType("button");

上一篇
[Day20] Babylon.js WebXR 高模組化功能:WebXR Experience Helper下的WebXR Features Manager
下一篇
Babylon.js GUI : 那些在XR世界中的2D畫面
系列文
WebXR未來新視界:Babylon.js打造Web的VR/AR/XR體驗22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言