Unity-編寫著色器時的性能技巧
僅執(zhí)行所需的計算
著色器代碼需要執(zhí)行的計算和處理越多,它對游戲性能的影響就越大。例如,支持每種材質(zhì)的顏色可以使著色器更加靈活,但如果始終將該顏色設(shè)置為白色,則會對屏幕上渲染的每個頂點或像素執(zhí)行無用的計算。
計算的頻率也會影響游戲的性能。通常,與頂點數(shù)(頂點著色器執(zhí)行次數(shù))相比,渲染的像素數(shù)會更多(因此像素著色器執(zhí)行次數(shù)也更多),而渲染的頂點數(shù)比渲染的對象更多。在可能的情況下,可將計算從像素著色器代碼移動到頂點著色器代碼中,或者將它們完全移出著色器并在腳本中設(shè)置值。
優(yōu)化的表面著色器
表面著色器非常適合編寫與光照交互的著色器。但是,它們的默認(rèn)選項已調(diào)整為涵蓋大量的一般情況。可針對特定情況調(diào)整這些選項以使著色器運(yùn)行速度更快,或至少讓著色器變得更小巧:
使用視圖方向(即鏡面反射)的著色器的?
approxview
?指令使視圖方向按照頂點(而不是按像素)進(jìn)行標(biāo)準(zhǔn)化。這是近似值,但通常足夠好。適用于鏡面反射著色器類型的?
halfasview
?速度更快。半矢量(光照方向和視圖矢量之間)按照頂點進(jìn)行計算和標(biāo)準(zhǔn)化,并且光照函數(shù)接受半矢量作為參數(shù),而不是視圖矢量。noforwardadd
?使著色器僅完全支持前向渲染中的單方向光。其余的光源仍然可提供每頂點光源或球諧函數(shù)光源的效果。這樣可以使著色器更小并確保它始終在一個通道中渲染,即使存在多個光源也是如此。noambient
?在著色器中禁用環(huán)境光照和球諧函數(shù)光源。這樣可以稍稍提高性能。
計算的精度
用 Cg/HLSL 編寫著色器時,有三種基本數(shù)字類型:float
、half
?和?fixed
(請參閱數(shù)據(jù)類型和精度)。
為獲得良好性能,請始終使用盡可能低的精度。這在移動平臺(如 iOS 和 Android)上尤為重要。重要的經(jīng)驗法則如下:
對于世界空間位置和紋理坐標(biāo),請使用?
float
?精度。對于所有其他情況(矢量、HDR 顏色等),請首先嘗試?
half
?精度。僅在必要的情況下再提高精度。要對紋理數(shù)據(jù)進(jìn)行非常簡單的運(yùn)算,請使用?
fixed
?精度。
實際上,具體應(yīng)該使用哪種數(shù)字類型取決于平臺和 GPU。一般來說:
所有新款的桌面端 GPU 將始終以完整?
float
?精度進(jìn)行所有計算,因此?float/half/fixed
?最終產(chǎn)生完全相同的結(jié)果。這可能會使測試變得困難,因為更難以確定 half/fixed 精度是否真正夠用,因此請始終在目標(biāo)設(shè)備上測試著色器以獲得準(zhǔn)確的結(jié)果。移動端 GPU 實際支持?
half
?精度。這種精度通常速度更快,并且使用更少的性能來執(zhí)行計算。Fixed
?精度通常僅對于較舊的移動端 GPU 有用。大部分新款 GPU(可運(yùn)行 OpenGL ES 3 或 Metal 的 GPU)在內(nèi)部以相同方式來處理?fixed
?和?half
?精度。
有關(guān)更多詳細(xì)信息,請參閱數(shù)據(jù)類型和精度。
Alpha 測試
固定函數(shù)?AlphaTest(或者其可編程的等效函數(shù)?clip()
)在不同平臺上具有不同的性能特征:
通常,在使用該函數(shù)來移除大多數(shù)平臺上的完全透明像素時,可獲得少量優(yōu)勢。
但是,在 iOS 和某些 Android 設(shè)備的 PowerVR GPU 上,Alpha 測試是資源密集型任務(wù)。不要試圖在這些平臺上使用這種測試進(jìn)行性能優(yōu)化,因為它會導(dǎo)致游戲運(yùn)行速度比平常慢。
顏色遮罩 (Color Mask)
在某些平臺(主要是 iOS 和 Android 設(shè)備的移動端 GPU)上,使用?ColorMask?省略一些通道(例如?ColorMask RGB
)可能是資源密集型的操作,所以除非絕對需要,否則請不要使用。