材質和著色器

請按照下列最佳做法,在 Android 遊戲中善用材質和著色器。

材質和著色器是現代 3D 藝術的核心基石。能在大部分裝置上順利執行的 3D 遊戲,會先採用專為充分利用圖像處理器而設計的 3D 藝術。這份指南說明材質和著色器在行動裝置上的最佳化與最佳做法,藉此提高遊戲效能並盡量降低耗電量。

本文部分內容以 Arm Limited 的著作為基礎,並受版權保護。

遊戲引擎行動裝置友善著色器

不同的遊戲引擎透過不同方式與材質和著色器建立關聯。Unity 引擎可以建立多個著色器,但每種材質只能獲派一個著色器。Unreal Engine 4 則能根據目標平台,為單一材質套用多個不同的著色器。

如需著色器和材質的定義,請參閱「適用於藝術家的材質和著色器最佳做法」一文。

如果你目前使用 Unity 或 Unreal Engine 4 等遊戲引擎,請使用專為行動裝置硬體設計的內建著色器。這類著色器包含經過簡化的功能實作,可提升在行動裝置上的效能。如果可以,請在設定材質時關閉未使用的功能,例如色調或細節對應等。停用未使用的功能可讓引擎從最終著色器程式中省略這類功能,藉此提升效能。

Unity

Unity 提供多種算繪引擎。針對現代化的手遊,最好的選擇是 Universal Render Pipeline (URP)。URP 提供一組標準著色器,可根據目標平台自動調整複雜的資源配置。舊版 Unity 轉譯器包含專為行動平台設計的一系列著色器。這些著色器會歸為「行動裝置」類別。

Unreal Engine 4

Unreal 引擎會根據所選的目標平台選擇行動著色器。行動著色器的影像輸出結果與預設的 Shader Model 5 著色器不同。你可以在 Unreal 編輯器中變更預覽算繪層級,以模擬行動著色器的算繪輸出結果。儘管存在一些差異,Unreal 在所有平台上都會以相同的程序處理材質,因此行動著色器的顯示效果和行為通常會類似預設著色器。

在 Unreal 編輯器中設定行動預覽算繪功能
圖 1 在 Unreal 編輯器中設定行動預覽算繪功能。

盡量減少紋理取樣數目

行動裝置專屬遊戲應在材質中盡量避免使用紋理。每增加一種紋理都需要額外進行紋理取樣,這會耗用記憶體頻寬並增加耗電量。Unreal Engine 4 建議在行動裝置上執行時,最多使用五個材質紋理。在許多裝置上,即使廣泛使用的只有 5 種紋理,也可能太過奢求。你可以採用下列策略盡量減少紋理取樣數量:

  • 使用紋理封裝功能合併單一管道紋理。如要進一步瞭解這項技巧,請參閱《紋理》指南。
  • 請將粗糙度或金屬等參數資料替換為常數,而非從紋理讀取資料。
  • 使用未打光著色器或簡易亮度模型,如此在較複雜的亮度模型中支援亮度計算時,就不需要使用紋理。

可能時停用亮度

著色器和材質通常可分成打光和未打光這兩種類型。即時亮度功能需要在著色器中進行額外的計算。根據所採用的亮度系統類型,你可能需要使用材質紋理,這會耗用較多記憶體空間和頻寬。如果是手機遊戲 (尤其是針對效能較弱硬體設計的遊戲),請盡量避免使用即時亮度功能,以便達到最佳效能。當你設計遊戲的藝術風格時,請考慮採用即使沒有亮度功能也能順利運作的設計,例如風格化或卡通式的藝術。

模型採用與未採用亮度功能進行算繪的比較
圖 2. 即時光源 (左側) 和沒有即時光源 (右側) 算繪的模型示例。

盡量避免使用透明度

請盡可能使用不透明的材質。算繪透明物件一定比算繪不透明的相同物件更昂貴。比起電腦或遊戲主機圖像硬體,行動圖像硬體的設計使得算繪透明度更加昂貴。如果在遊戲中繪製許多透明物件 (尤其是彼此相疊進行算繪),將會使效能降低。

重覆繪製相同的像素,這個問題稱為過度繪製。請避免過度繪製多層透明度。許多遊戲都有診斷工具,以視覺化方式呈現過度繪製狀態,協助偵測及避免這種情形。使用這些工具提升遊戲效能,並找出導致畫面更新率降低的問題區。

Unity 編輯器中的過度繪製視覺化工具示例
圖 3 Unity 編輯器中的過度繪製視覺化工具示例。
Unreal 編輯器中的過度繪製視覺化工具示例
圖 4. Unreal 編輯器中的過度繪製視覺化工具示例。

使用適當的 Alpha 版測試法

最常見的透明度實作方法是 Alpha 版混合與 Alpha 版測試。

Alpha 版測試會讓物件材質看起來完全不透明或完全透明。你可為這項區隔設定 Alpha 版值門檻。在 Unity 中,這種透明度稱為「凹口」,在 Unreal Engine 4 中則稱為「遮罩」混合模式。

Alpha 版混合能讓物件材質具有一定程度的透明度,並讓物件看起來半透明。Unity 將這種類型的透明度稱為「透明」,在 Unreal Engine 4 中則稱為「半透明」混合模式。

Alpha 版混合和 Alpha 版測試的比較
圖 5 使用 Alpha 混合功能 (中間) 和 Alpha 測試 (右側) 算繪的範例圖片 (左側)。

Alpha 版混合的視覺效果通常比 Alpha 版測試更佳。不過,Alpha 版混合會讓某些類型的網格 (例如樹葉) 在動態下看起來很奇怪,這是因為枝葉的算繪順序明顯有誤。Alpha 版測試能避免這樣的問題,但枝葉邊緣會較容易出現鋸齒和鋒利稜角。

Alpha 版混合與 Alpha 版測試算繪相同網格所需的時間可能不同。如果網格在這兩種模式下的視覺輸出結果都可接受,你應設定基準來確認兩種方法的效能孰優孰劣。

剖析著色器複雜度

紋理取樣、亮度和透明度等算繪功能都會提升著色器的複雜度,並降低算繪效能。你可以使用遊戲引擎內建工具和外部圖像工具,來評估著色器的複雜度。

Unreal Engine 4 提供「著色器複雜度」檢視模式,可為場景中的物件計算預估費用。

Unreal 編輯器中的「著色器複雜度」檢視模式
圖 6:Unreal 編輯器中的「著色器複雜性」檢視模式。

你也可以使用 Unreal 的「材質統計資料」功能,在編寫材質時剖析相關成本。

Unreal 編輯器中的「材質統計資料」顯示畫面
圖 7:Unreal 編輯器中的「Material 統計資料」

在頂點著色器中進行計算

算繪著色器依據計算方式,通常分成頂點著色器和片段 (又稱為「像素」) 著色器,而算繪的片段數量通常大於頂點的數量。如果可在頂點著色器中執行昂貴的運算,則執行頻率會比在片段著色器中執行的頻率低。

不過,這項資料如果會由片段著色器使用,則必須從端點著色器傳遞。如果傳輸的資料量過大,那麼在片段著色器中執行計算的效能可能較高。 你可以使用剖析工具來評估建構器使用率,以便決定執行一組計算的最佳著色器位置。Unreal Engine 4 提供自訂 UV 功能,可協助您進行剖析。

避免執行昂貴的數學運算

著色器程式中會用到數學運算,以控制著色器輸出的行為和外觀。一般運算包括基本算術、次方、下取整函數、對數等。數學運算和電腦運算的費用不同。如果著色器填滿了昂貴的運算,效能就會較慢,尤其是在舊型裝置上。有些運算的費用則相對低廉,例如:

  • 加法
  • 減法
  • 乘法

較昂貴的作業包括:

  • 除法
  • 超越數 (sin、cos、power、log、tan)

頻繁剖析效能

不是每個效能瓶頸都顯而易見。請避免假設問題起因,並應利用剖析工具來評估算繪效能。在進行最佳化前後,請一律進行測試,以確保準確評估影響程度。