全像投影防震 - MRTK2

效能

為了讓基礎混合實境平臺和裝置產生最佳結果,請務必達到執行幀速率。 目標幀速率 (例如:60 FPS 或 90 FPS) 會因平臺和裝置而異。 不過,混合實境應用程式會議幀速率會有穩定的全像投影,以及有效率的頭部追蹤、手部追蹤等等。

環境追蹤

穩定的全像攝影轉譯高度依賴平臺 & 裝置的頭部姿勢追蹤。 Unity 會呈現基礎平台所估計和提供之相機的每個畫面格的場景。 如果此追蹤未正確遵循實際的頭部移動,則全像投影會以視覺方式呈現不正確。 這在 HoloLens 這類 AR 裝置中特別明顯且很重要,使用者可以將虛擬全像投影與真實世界產生關聯。 效能對於可靠的前端追蹤很重要,但也有 其他重要功能。 影響用戶體驗的環境元素類型將取決於目標平臺特定專案。

Windows Mixed Reality

Windows Mixed Reality 平臺提供一些參考數據,以穩定平臺上的全像投影。 不過,開發人員可以使用幾個重要工具來改善使用者的全像投影視覺體驗。

深度緩衝區共用

Unity 開發人員可以選擇與平臺共用應用程式的深度緩衝區。 這提供目前框架的全像投影存在的信息,平臺可以透過稱為 Late-Stage Reprojection 的硬體輔助程式來穩定全像投影。

晚期階段重現

在轉譯框架結束時,Windows Mixed Reality 平臺會採用應用程式所產生的色彩 & 深度轉譯目標,並轉換最終屏幕輸出,以考慮自上一個頭部姿勢預測之後的任何稍微頭部移動。 應用程式的遊戲迴圈需要一段時間才能執行。 例如,在 60 FPS 時,這表示應用程式會採用 ~16.667 毫秒來轉譯畫面。 雖然這看起來可能有點微的時間量,但用戶頭部的位置和方向也會變更,導致相機在轉譯時產生新的投影矩陣。 晚期階段重現會轉換最終影像中的圖元,以考慮這個新的檢視方塊。

每像素與防震平面 LSR

根據在 Windows Mixed Reality 裝置上執行的裝置端點和 OS 版本,Late-Stage 重新投影演算法將會執行每像素或透過防震平面執行。

每像素深度型

每個圖元深度型重現牽涉到利用深度緩衝區來修改每個圖元的影像輸出,因而以各種距離穩定全像投影。 例如,球體 1m 距離可能位於距離 10m 的柱子前面。 代表球體的圖元會與遠距離圖元不同的轉換,如果使用者稍微傾斜其頭部,則代表柱形。 每個圖元的重現都會考慮每個圖元的距離差異,以取得更精確的重現。

防震平面

如果無法建立精確的深度緩衝區來與平台共用,另一種形式的 LSR 會利用防震平面。 場景中的所有全像投影都會收到一些防震,但位於所需平面的全像投影將會收到最大硬體防震。 平面的點和標準可透過 Unity 提供的HolographicSettings.SetFocusPointForFrame API 提供給平臺。

深度緩衝區格式

如果以 HoloLens 為目標進行開發,強烈建議使用相較於 24 位的 16 位深度緩衝區格式。 這可以大幅節省效能,雖然深度值會有較少的精確度。 若要補償較低的精確度並避免 z 衝突,建議從 Unity 所設定的 1000m 預設值中減少 遠距裁剪平面

注意

如果使用 16位深度格式,樣板緩衝區所需的效果將無法運作,因為 Unity 不會在此設定中 建立樣板緩衝區 。 如果端點圖形平臺上適用,則選取 24 位深度格式 通常會建立 8 位樣板緩衝區

Unity 中的深度緩衝區共用

為了利用深度型 LSR,開發人員需要採取兩個重要步驟。

  1. [編輯>項目設定>] 下的 [播放程式>XR 設定>] [虛擬現實 SDK> ] 下,啟用 深度緩衝區共用
    1. 如果以 HoloLens 為目標,建議您也選取 16 位深度格式
  2. 在畫面上呈現色彩時,也會轉譯深度

Unity 中的不透明 GameObject 通常會自動寫入深度。 不過,透明 & 文字對象預設不會寫入深度。 如果使用 MRTK 標準著色器或文字網格 Pro,則可以輕鬆地解決此問題。

注意

若要快速判斷場景中哪些物件不會以可視化方式寫入深度緩衝區,您可以在 MRTK 組態配置檔的編輯器設定下使用轉譯深度緩衝區公用程式

透明 MRTK 標準著色器

針對使用 MRTK 標準著色器的透明材質,請選取材質以在 [偵測器 ] 視窗中檢視。 然後按兩下 [ 立即修正 ] 按鈕,將材質轉換成深度 (,例如 Z-Write On) 。

之前

修正 MRTK 標準著色器之前的深度緩衝區

After

深度緩衝區固定 MRTK 標準著色器

文字網格 Pro

針對 Text Mesh Pro 物件,選取 TMP GameObject 以在偵測器中檢視它。 在材質元件下,切換指派材質的著色器,以使用 MRTK TextMeshPro 著色器。

文字網格 Pro 深度緩衝區修正

自定義著色器

如果撰寫自定義著色器,請將 ZWrite 旗 標新增至 Pass 區塊定義的頂端,以設定著色器以寫入深度緩衝區。

Shader "Custom/MyShader"
{
    SubShader
    {
        Pass
        {
            ...
            ZWrite On
            ...
        }
    }
}
不透明備份

如果上述方法不適用於指定的案例 (,也就是使用 Unity UI) ,則可能會有另一個物件寫入深度緩衝區。 常見的範例是在場景中的浮動面板上使用 Unity UI 文字。 藉由讓面板不透明或至少要寫入深度,則面板 & 面板的兩個文字都會受到平臺的穩定,因為它們的 z 值彼此相近。

WorldAnchors (HoloLens)

除了確保符合正確的設定以確保視覺穩定性之外,請務必確保全像投影在其正確的實體位置保持穩定。 為了通知平臺在實體空間中的重要位置,開發人員可以在 GameObjects 上利用需要留在某個位置的 WorldAnchorsWorldAnchor 是新增至 GameObject 的元件,可絕對控制該物件的轉換。

HoloLens 之類的裝置會持續掃描並了解環境。 因此,當 HoloLens 追蹤空間中的行動 & 位置時,其估計值將會更新, 並調整 Unity 座標系統。 例如,如果GameObject從相機開始放置1m,因為HoloLens追蹤環境,它可能會發現GameObject實際位於1.1公分的實體點。 這會導致全像投影漂移。 將 WorldAnchor 套用至 GameObject 可讓錨點控制物件的轉換,讓對象維持在正確的實體位置 (,也就是在運行時間) 更新為 1.1m,而不是 1m。 若要跨應用程式會話保存 WorldAnchors ,開發人員可以使用 WorldAnchorStore儲存和載入 WorldAnchors

注意

將 WorldAnchor 元件新增至 GameObject 之後,就無法修改 GameObject 的轉換 (亦即 transform.position = x) 。 開發人員必須移除 WorldAnchor 才能編輯轉換。

WorldAnchor m_anchor;

public void AddAnchor()
{
    this.m_anchor = this.gameObject.AddComponent<WorldAnchor>();
}

public void RemoveAnchor()
{
    DestroyImmediate(m_anchor);
}

如果您想要手動使用錨點的替代方案,請參閱 Microsoft World 鎖定工具。

另請參閱