全像投影防震 - MRTK2

效能

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

環境追蹤

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

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. [編輯>Project 設定>Player>XR 設定>虛擬實境 SDK> 啟用深度緩衝區共用
    1. 如果以HoloLens為目標,建議您也選取16 位深度格式
  2. 在畫面上呈現色彩時,也會轉譯深度

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

注意

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

透明 MRTK 標準著色器

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

之前

Depth Buffer Before Fix MRTK Standard Shader

After

Depth Buffer Fixed MRTK Standard Shader

文字Mesh Pro

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

Text Mesh Pro Depth Buffer Fix

自訂著色器

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

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

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

WorldAnchors (HoloLens)

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

HoloLens之類的裝置會持續掃描並瞭解環境。 因此,當HoloLens追蹤空間中的移動 & 位置時,其估計值將會更新,並調整 Unity 座標系統。 例如,如果 GameObject 從相機開始放置 1 公分,因為HoloLens追蹤環境,它可能會發現 GameObject 實際位於 1.1m 的實體點。 這會導致全像投影漂移。 將 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 鎖定工具。

另請參閱