效能 - MRTK2

開始使用

合理化效能的最簡單方式是透過幀速率,或您的應用程式每秒可以轉譯影像的次數。 請務必符合目標幀速率,如目標平臺所概述 (,例如 Windows Mixed Reality、等) 。 例如,在 HoloLens 上,目標幀速率為 60 FPS。 低幀速率應用程式可能會導致豐富的用戶體驗,例如穩定的 全像投影防震、世界追蹤、手部追蹤等等。 為了協助開發人員追蹤並達到品質框架,Mixed Reality 工具組提供各種工具和腳本。

可視化分析工具

若要持續追蹤開發生命週期的效能,強烈建議在執行 & 偵錯應用程式時,一律顯示幀速率視覺效果。 Mixed Reality 工具組提供 Visual Profiler 診斷工具,可提供應用程式檢視中目前 FPS 和記憶體使用量的實時資訊。 Visual Profiler 可以透過 MRTK 設定檔偵測器下的診斷系統設定來設定。

此外,利用 Visual Profiler 在裝置上執行時追蹤幀速率,而不是在 Unity 編輯器或模擬器中執行時,特別重要。 使用 發行組態組建在裝置上執行時,將會描述最精確的效能結果。

注意

如果建置 Windows Mixed Reality,請使用 MASTER 組態組建進行部署。

Visual Profiler 介面

優化視窗

MRTK 優化視窗提供資訊和自動化工具,協助混合實境開發人員設定其環境,以獲得最佳執行的結果,並找出其場景中 & 資產的潛在瓶頸。 Unity 中的某些重要設定有助於為混合實境專案提供更優化的結果。

一般而言,這些設定涉及轉譯適合混合實境的設定。 相較於傳統的 3D 圖形開發,混合實境應用程式是唯一的,其中有兩個畫面 (也就是兩個眼睛) 來呈現整個場景。

您可以利用 MRTK 優化視窗,在 Unity 專案中自動設定以下參考的建議設定。

MRTK 優化視窗設定

Unity Profiler

Unity Profiler 是一個實用的工具,可用來調查逐一畫面格層級的應用程式效能詳細數據。

花費在 CPU 上的時間

範例 Unity Profiler Graph

若要維持 (通常每秒 60 個畫面格) 的熟悉幀速率,應用程式必須達到最大幀時間 16.6 毫秒的 CPU 時間。 為了協助識別 MRTK 功能的成本,Microsoft Mixed Reality 工具組包含每個畫面) 程式代碼路徑 (內部循環的標記。 這些標記會使用下列格式,以協助瞭解所使用的特定功能:

[MRTK] className.methodName

注意

方法名稱之後可能會有其他數據。 這可用來識別有條件地執行、可能昂貴的功能,這些功能可能會因應用程式程式代碼的小型變更而避免。

Unity Profiler 階層範例

在此範例中,階層已展開以顯示在分析框架期間,WindowsMixedRealityArticulatedHand 類別的 UpdateHandData 方法耗用 0.44 毫秒的 CPU 時間。 此數據可用來協助判斷效能問題是否與應用程式程式碼或系統中的其他位置有關。

強烈建議開發人員以類似的方式檢測應用程式程式代碼。 應用程式程式代碼檢測的主要焦點區域是在事件處理程式中,因為這些方法會在引發事件時向 MRTK 更新循環收費。 MRTK 更新迴圈內的高框架時間可能表示事件處理程式方法中的昂貴程序代碼。

Single-Pass 實例轉譯

Unity 中 XR 的預設轉譯組態是 多階段。 此設定會指示 Unity 針對每個眼睛執行整個轉譯管線兩次。 您可以改為選取 [單一傳遞實例轉譯 ] 來優化此功能。 此組態會利用 轉譯目標數位 來執行單一繪製呼叫,該呼叫實例會針對每個眼睛適當 轉譯目標 。 此外,此模式允許在轉譯管線的單一執行中完成所有轉譯。 因此,選取 [單一傳遞實例轉譯] 作為混合實境應用程式的轉譯路徑,可 節省CPU & GPU 的大量時間 ,而且是建議的轉譯組態。

不過,為了為每個眼睛發出每個網格的單一繪製呼叫,所有著色器都必須支援 GPU 實例 。 實例可讓 GPU 跨兩眼繪製呼叫多倍。 Unity 內建著色器和 MRTK 標準著色器 預設包含著色器程式代碼中必要的實例指示。 雖然針對 Unity 撰寫自定義著色器,則可能需要更新這些著色器以支援單一傳遞實例轉譯。

自定義著色器的範例程序代碼

struct appdata
{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;

    UNITY_VERTEX_INPUT_INSTANCE_ID //Insert
};

struct v2f
{
    float2 uv : TEXCOORD0;
    float4 vertex : SV_POSITION;

    UNITY_VERTEX_OUTPUT_STEREO //Insert
};

v2f vert (appdata v)
{
    v2f o;

    UNITY_SETUP_INSTANCE_ID(v); //Insert
    UNITY_INITIALIZE_OUTPUT(v2f, o); //Insert
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); //Insert

    o.vertex = UnityObjectToClipPos(v.vertex);

    o.uv = v.uv;

    return o;
}

質量設定

Unity 提供 預設,以控制 每個平臺端點的轉譯品質。 這些預設可控制哪些圖形化功能可以啟用,例如陰影、反別名、全域照明等等。 建議您降低這些設定,並將轉譯期間執行的計算數目優化。

步驟 1: 更新混合實境 Unity 專案以使用 低品質 層級設定
編輯>項目設定,然後選取 [ 品質 ] 類別 > 選取 UWP 平臺的 [低品質 ]

步驟 2: 針對每個 Unity 場景檔案,停用 即時全域照明
視窗>渲染>光源設定>取消核取 即時全域照明

HoloLens) (深度緩衝區共用

如果針對 Windows Mixed Reality 平臺和特別是 HoloLens 進行開發,請在 XR 設定下啟用深度緩衝區共用有助於全像投影防震。 不過,深度緩衝區的處理可能會產生效能成本,特別是在使用 24位深度格式時。 因此, 強烈建議 您將深度緩衝區設定為16位精確度。

如果因為較低的位格式而發生 z-fighting ,請確認所有相機的 遠剪輯平面 都設定為應用程式的最低可能值。 Unity 預設會設定遠距裁剪平面 1000m。 在 HoloLens 上,大部分應用程式案例的遠距裁剪平面通常超過 50m。

注意

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

如果使用需要樣板緩衝區的 Mask元件 ,請考慮改用 RectMask2D ,這不需要樣板緩衝區,因此可以搭配 16位深度格式使用。

注意

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

優化網格數據

[優化網格數據] 設定會嘗試移除應用程式中未使用的頂點屬性。 此設定會藉由在每個著色器上執行,以傳入組建中每個網格上的每個材質來執行此動作。 這適用於遊戲數據大小和運行時間效能,但可能會大幅阻礙建置時間。

建議您在開發期間停用此設定,並在建立「主要」組建期間重新啟用。 您可以在 [編輯>項目設定>] [播放程式>其他設定>] [優化網格數據] 下找到設定。

一般建議

效能對於混合實境開發人員而言可能是模棱兩可且不斷變化的挑戰,以及合理化效能的知識範圍相當龐大。 不過,有一些一般建議可用來瞭解如何處理應用程式的效能。

將應用程式執行簡化為 在 CPUGPU 上執行的片段,進而識別應用程式是否受到任一元件所系結。 可能會有一些瓶頸跨越處理單位和一些必須仔細調查的獨特案例。 不過,若要開始使用,最好能掌握應用程式執行時間最多的時間。

GPU 系結

由於混合實境應用程式的大部分平臺都使用 立體轉譯,因此因為轉譯「雙寬」屏幕的本質,所以非常常見於 GPU 系結。 此外,HoloLens 或 Aus Quest 等行動混合實境平臺將會受到行動類別 CPU & GPU 處理能力的限制。

將焦點放在 GPU 上時,應用程式必須完成每個畫面的兩個重要階段。

  1. 執行 頂點著色器
  2. 執行 圖元著色器 (也稱為片段著色器)

若不深入探討計算機圖形 & 轉譯管線的複雜領域,每個著色器階段都是在 GPU 上執行以產生下列專案的程式。

  1. 頂點著色器會將網格頂點轉換成螢幕空間 (中的座標,也就是針對每個頂點執行的程式碼)
  2. 圖元著色器會計算要針對指定圖元和網格片段繪製的色彩 (,也就是針對每個像素執行程序代碼)

關於效能微調,通常更不小心將焦點放在優化圖元著色器中的作業。 應用程式可能只需要繪製只有 8 個頂點的 Cube。 不過,Cube 佔用的螢幕空間可能以數百萬像素為單位。 因此,假設 10 個作業減少著色器程式代碼,如果圖元著色器比頂點著色器減少,可以大幅節省更多工作。

這是利用 MRTK 標準著色 器的主要原因之一,因為此著色器通常會執行比 Unity 標準著色器少許多指令 & 頂點的指示,同時達到可比較的美感結果。

CPU 優化 GPU 優化
應用程式模擬邏輯 轉譯作業
簡化物理 減少光源計算
簡化動畫 減少可繪製物件的多邊形計數 & #
管理垃圾收集 減少透明物件的 #
快取參考 避免後置處理/全螢幕效果

繪製呼叫實例

Unity 中最常見的錯誤之一,就是在運行時間複製材質。 如果 GameObjects 共用相同的材質和/或是相同的網格,則可以透過 靜態批處理動態批處理GPU 實例等技術,將其優化成單一繪製呼叫。 不過,如果開發人員在運行時間修改 轉譯器材質 的屬性,Unity 將會建立指派之材質的複製副本。

例如,如果場景中有100個 Cube,開發人員可能會想要在運行時間為每個 Cube 指派唯一色彩。 C# 中 renderer.material.color 的存取權會讓 Unity 為此特定轉譯器/GameObject 在記憶體中建立新的材質。 每個 100 個 Cube 都有自己的材質,因此無法合併成一個繪製呼叫,而是會變成 100 個從 CPU 到 GPU 的繪製呼叫要求。

為了克服此障礙,並仍然為每個 Cube 指派唯一色彩,開發人員應該利用 MaterialPropertyBlock

private PropertyBlock m_PropertyBlock ;
private Renderer myRenderer;

private void Start()
{
     myRenderer = GetComponent<Renderer>();
     m_PropertyBlock = new MaterialPropertyBlock();
}

private void ChangeColor()
{
    // Creates a copy of the material once for this renderer
    myRenderer.material.color = Color.red;

    // vs.

    // Retains instancing capability for renderer
    m_PropertyBlock.SetColor("_Color", Color.red);
    myRenderer.SetPropertyBlock(m_PropertyBlock);
}

Unity 效能工具

Unity 提供內建在編輯器中的絕佳效能工具。

如果估計一個著色器與另一個著色器之間的粗略效能取捨,則編譯每個著色器並檢視每個著色器階段的作業數目很有用。 您可以選取 著色器資產 ,然後按兩下 [ 編譯並顯示程式代碼 ] 按鈕來完成。 這會編譯所有著色器變體,並開啟具有結果的Visual Studio。 注意:產生的統計數據結果可能會因使用指定著色器而啟用哪些特徵而有所不同。 Unity 只會編譯目前專案中直接使用的著色器變體。

Unity 標準著色器統計數據範例

Unity 標準著色器統計數據 1

MRTK 標準著色器統計數據範例

MRTK 標準著色器統計數據 2

另請參閱

Unity

Windows Mixed Reality

網格優化