優(yōu)化著色器加載時間
著色器是在 GPU 上執(zhí)行的小程序,加載它們可能需要一些時間。每個單獨的 GPU 程序通常不會花費很多時間來加載,但著色器通常在內(nèi)部有很多“變體”。
例如,標(biāo)準(zhǔn)著色器在完全編譯后,最終將成為數(shù)千個略微不同的 GPU 程序。這種情況可產(chǎn)生兩個潛在問題:
大量的這些著色器變體將增加游戲構(gòu)建時間和游戲數(shù)據(jù)大小。
在游戲過程中加載大量著色器變體將很慢并占用內(nèi)存。
著色器構(gòu)建時剝離
在構(gòu)建游戲時,Unity 可能檢測到游戲不使用某些內(nèi)部著色器變體,并從構(gòu)建數(shù)據(jù)中跳過它們。構(gòu)建時剝離將用于以下各項:
各個著色器功能(針對使用?
#pragma shader_feature
?的著色器)。如果所使用的材質(zhì)都不使用特定變體,則該變體不會包含在構(gòu)建中。請參閱內(nèi)部著色器變體文檔。在內(nèi)置著色器中,標(biāo)準(zhǔn)著色器會使用構(gòu)建時剝離。任何場景未使用的可處理霧效和光照貼圖模式的著色器變體不會包含在游戲數(shù)據(jù)中。如果要重寫此行為,請參閱圖形設(shè)置。
上述的組合通常會大大減小著色器數(shù)據(jù)大小。例如,完全編譯后的標(biāo)準(zhǔn)著色器將占用幾百兆字節(jié),但在典型的項目中,通常最終僅占用幾兆字節(jié)(并且通常會由應(yīng)用程序打包過程進(jìn)一步壓縮)。
默認(rèn)的 Unity 著色器加載行為
在所有默認(rèn)設(shè)置下,Unity 將?shaderlab 著色器對象加載到內(nèi)存中,但在實際需要之前不會創(chuàng)建內(nèi)部著色器變體。
這意味著仍然可以使用包含在游戲構(gòu)建中的著色器變體,但是在需要它們之前不會有內(nèi)存或加載時間成本。例如,著色器總是包含一個變體用于處理帶陰影的點光源,但是如果一直未能在游戲中使用帶陰影的點光源,那么加載這個特定的變體是沒有意義的。
然而,這種默認(rèn)行為有一個缺點,即第一次需要某個著色器變體時可能會出現(xiàn)暫時性中斷問題,這是因為必須將新的 GPU 程序代碼加載到圖形驅(qū)動程序中。在游戲過程中通常不希望發(fā)生這種問題,因此 Unity 提供了?ShaderVariantCollection?資源來幫助解決該問題。
著色器變體集合
ShaderVariantCollection 資源基本上是一個著色器列表,對于每個著色器,都要加載一組 pass 類型和著色器關(guān)鍵字組合。

為了幫助根據(jù)實際使用的著色器及其變體來創(chuàng)建這些資源,編輯器可以跟蹤實際使用的著色器及其變體。在 Graphics Settings 中,有一個按鈕可基于當(dāng)前跟蹤的著色器創(chuàng)建新的 ShaderVariantCollection,或清除當(dāng)前跟蹤的著色器列表。

有了一些 ShaderVariantCollection 資源后,即可設(shè)置在加載應(yīng)用程序時自動預(yù)加載這些變體(位于?Graphics Settings?中的 Preloaded Shaders 列表下),或者也可從腳本預(yù)加載單個著色器變體集合。
Preloaded Shaders 列表列出的是常用著色器。此處列出的著色器變體將在應(yīng)用程序的整個生命周期內(nèi)加載到內(nèi)存中。對于包含大量變體的 ShaderVariantCollections 資源,這可能會占用大量內(nèi)存。為避免這種情況,應(yīng)以較小的粒度創(chuàng)建 ShaderVariantCollection 資源并從腳本進(jìn)行加載。一種策略是為每個場景記錄使用過的著色器變體,將它們保存到單獨的 ShaderVariantCollections 資源中,并在場景啟動時加載它們。
請參閱?ShaderVariantCollection?腳本類。