Shader山下(二十一)多重變體(Multiple Variants)

Shader山下(二十)編譯指令(Compilation Directives)介紹瞭如何使用編譯指令,本文就專文介紹一下多重編譯(multi_compile)指令。

咱們可使用multi_compile來爲shader建立多個稍微有點區別的shader變體。這個Shader被稱爲宏着色器(mega shader)或者超着色器(uber shader)。實現原理:根據不一樣的狀況,使用不一樣的預處理器指令,來屢次編譯Shader代碼。html

在Unity裏面,可使用:cookie

#pragma multi_compile

#pragma shader_feature

兩個指令來實現。適用於VF着色器和表面着色器。編輯器

運行時,會根據材質(Material)的關鍵字(Material的對象方法EnableKeyword和DisableKeyword)或者全局着色器關鍵字(Shader的類方法EnableKeyword和DisableKeyword)。ide

注:以前在Shader山下(十二)材質屬性繪製器裏,咱們已經介紹了多重編譯的運用性能

 

使用multi_compile指令:測試

#pragma multi_compile TEST_OFF TEST_ON


這樣會編譯兩個Shader變體,一個是TEST_OFF的版本,一個是TEST_ON的版本。運行的時候會根據材質關鍵之或者Shader全局關鍵字判斷應該使用哪一個,若是兩個關鍵字都爲false,那麼會使用第一個(TEST_OFF)變體。優化

咱們也能夠建立多個關鍵字:spa

#pragma multi_compile TEST_A TEST_B TEST_C TEST_D


或者只建立一個關鍵字,這時候就須要使用__來代替另外一個:.net

#pragma __ TEST_KEY_ON

這樣依然會生成兩個shader變體,一個啥都沒定義,另一個定義了TEST_KEY_ON。3d


咱們還能夠經過多行指令來組合關鍵字:​​​​​​​

#pragma multi_compile A B C

#pragma multi_compile D E

這樣就會生成六個shader變體(A+D、B+D、C+D、A+E、B+E、C+E)。可是這樣shader變體的數量就可能會變得不少,10行multi_compile,每行有兩個關鍵字,那麼就會有1024個shader變體。

除了multi_compile以外,還有另一個相似的指令shader_feature,惟一的區別在於shader_feature不會將不用的shader變體添加到程序中去。shader_feature更適用於材質的關鍵字,而multi_compile更適用於代碼設置的全局關鍵字。

示例:

#pragma shader_feature TEST_STUFF


這是下面這種寫法的簡寫形式:

#pragma shader_feature __ TEST_STUFF

注:Unity中最多能夠有128個關鍵字,可是Unity本身已經定義了一部分了,因此實際上會更少。因此使用multi_compile和shader_feature的時候,就須要特別注意不要超過這個限制。

 

Unity自身還內建一些multi_compile的快捷寫法:

multi_compile_fwdbase:爲基本前向渲染通道編譯多個變體,不一樣的變體可能須要處理不一樣的光照貼圖類型,或者一些使用了主平行光的陰影,而另外一些禁用了。(參考Unity渲染管線

multi_compile_fwdadd:爲附加前向渲染通道編譯多個變體,不一樣的變體可能須要處理不一樣類型的光源——平行光、聚光燈或者點光源,亦或者它們附帶cookie紋理的版本。

multi_compile_fwdadd_fullshadows:同上,不過包含了可讓光源擁有實時陰影的功能。

multi_complie_fog:爲處理不一樣的霧效類型(off/linear/exp/exp2)擴展了多個變體。

 

大部份內建快捷寫法會致使許多shader變體,若是某些不須要使用,那麼可使用#pragma skip_variants來忽略它們。

#pragma multi_compile_fwdadd

// will make all variants containing

// "POINT" or "POINT_COOKIE" be skipped

#pragma skip_variants POINT POINT_COOKIE

 

使用multi_compile的目的通常是爲了建立一些fallback或者簡化shader,它們在同一個目標平臺(例如OpenGL ES)的高端硬件和低端硬件上均可以高效地運行。這種時候,咱們可使用shader硬件變體來爲不一樣性能等級的硬件建立一個特殊優化的變體集合。

爲了生成shader硬件變體,須要添加#pragma hardware_tier_variantsrenderer,這裏renderer表示某個可運行的渲染平臺。使用這個指令,Unity會對每一個shader生成3個shader變體(其餘關鍵字會不起做用),而對應的關鍵字是:

UNITY_HARDWARE_TIER1

UNITY_HARDWARE_TIER2

UNITY_HARDWARE_TIER3

在編輯器裏,能夠經過Graphics Emulation菜單來測試他們。

注:這些shader並不受Quality Setting的影響,它們純粹是經過檢測GPU的相關性能來決定的。

相關文章
相關標籤/搜索