表面着色器分析。
ok這個視訊來分析一下表面着色器的實力。這個會做一個小人的模型的膨脹,對模型進行膨脹。這是這個模型,拖動它就會讓它膨脹,就是模型的膨脹。這種效果實作就是在頂點修改函數中沿着頂點法線方向擴張頂點位置。
為了分析表面着色其中四個可定性自定義函數頂點修改函數,表面函數光照函數和最後的顔色修改函數的原理,接下來這個函數全部采用自定義的實作,來看一下它的代碼。
這個就是首先partitis定義面闆的屬性還有subsider,對結構體。然後在頂點修改函數中,使用頂點法線對頂點位置進行膨脹。表面函數使用主紋理設定了表面屬性中的反射率,并使用法線紋理設定了表面法線方向,光照函數實作了簡單的蘭博特反射函數。
光照模型在最後的顔色修改函數中,簡單使用了顔色參數對輸出顔色進行調整。終于除了四個函數外,在program surface的編譯指令中還指出了一個額外的參數。在這裡由于修改了定電位置,是以要對其物體産生正确的陰影效果,并不能直接依賴 fourbag中找到的陰影陰影投射獎pass。
而色素參數可以告訴我們,因為題要生成一個該表面着色器對應的陰影同時 pass。預設情況下應體會為支撐所支援的渲染路徑生成相應的 pass。為了縮小自動生成的代碼量,使用了include pass deferred和 include passpropass來告訴應用體不要為延遲渲染路徑生成相應的 pass。
最後使用nomait參數取消,采取元素原資料的 pass 的生成。當在該表面着色器的導入面闆中單擊so jerryt 的 code 按鈕後就可以看到應用體生成的頂點片緣着色器元素的生成。
接下來來需要看一下在不一樣的用體版本中會生成的代碼有許多不同。然後接下來來看一下這個。首先來看第一個方向渲染,在用體中生成前向渲染 pass的分析。
·首先看第一點,這裡這裡是頂點着色器word serve和片緣着色器 frank serve都是自動生成的這些。然後之後出現的是一些自動生成的注視,就是這些注視。
·接下來就是這一個,看unity會定義一些紅來輔助計算。在這裡實際上就是這些紅并沒有被用。用到這些紅是為了在修改了表面法線的情況下輔助計算得到世界空間下的反射方向和法線方向與之對應的是input結構體中的一些變量。
·接着unt把表面着色器編譯的 c g 代碼複制過來,作為 pass 的一部分,友善後續調用。
unt定義了頂點着色器到片緣着色器的內插補點結構及頂點着色器的輸出結構。r f aux在定義之前 unt 使用僅isif語句來判斷是否生成。使用光照紋理并為不同的情況生成不同的結構體,主要的差別是如果沒有使用光照紋理,就需要定義一個存儲竹頂點和 s h光照的變量。下邊是這個,除了它的結構體之外,就看它的光照變亮。
在這裡邊有很多變量看起來比較陌生,但實際上大部分變量的含義在之前有碰到過,隻是在這裡使用了不同的名稱而已。
比如說在下面看到b big 0中,實際上存儲的就是主紋理和法線紋裡的采樣坐标。而e 1cm space 0.2cm存儲了從切線空間到世界空間的變換。矩陣一個比較陌生的變量是be light,應用題會把主頂點和 s h光照的結果存儲到該變量裡,并在片緣着色器中中和雲光照結果進行疊加。
随後用題定義了真正的頂點着色器。頂點着色器首先會調用自定義的頂點修改函數來修改一些屬性,也是他的頂點着色器。頂點着色器用于計算vrf stag中各個變量的值。
比如說計算經過x v difference變化的頂點坐标使用 light v 内置紅,計算兩個紋理的采樣坐标并分别存儲在o 點 source x y 分和z w分量中。計算從傾斜空間到世界空間的變換矩陣,并把矩陣的每一行分别存儲在o 點 t space 0.o 點 t space 一 o 點 t space 2變量中。
判斷是否使用了光照映射和動态光照映射,并在需要時把兩種光照紋理的采樣坐标計算結果存儲在o 點 lamp x y和o 點 l lamp z w分兩種判斷。
是否使用了光照映射,如果沒有就計算該頂點的 sh光照,它是一種快速計算光照的方法,把結果存儲在o v light中。判斷是否開啟了主頂點光照,如果是就計算最重要的四個主頂點光照的光照結果,把結果疊加到o v light中這部分代碼。
可以在後面看,然後接下來看起陰影坐标傳遞給片圓着色器,接下來是會在pass的最後用題定義了真正的片圓着色器。
用題是首先利用叉指後的結構體vrs 裸來初始化input結構體的變量。這一塊,随後 unit 聲明了一個 surface output結構體的變量,并對其中的表面屬性進行了初始化,再調用了表面函數。在這些代碼中unit 會使用了井 eve deface這個語句判斷目前的編譯語言類型是否是h s l ver 意思。
如果是用更嚴格的聲明方式來表示就是surface output結構體。因為斡平台往往有更加嚴格的語音要求,當對各個表面屬性進行初始化後,用體要用了表面函數 self來填充這些表面屬性之後用題進行了真正的光照計算。
首先計算得到光照衰減和世界空間下的法線坐标,在這裡計算了光照衰竭和世界空間下的法線坐标,其中這裡的變量c是用于存儲最終的輸出顔色,此時被初始化為零。随後應題判斷是否關閉光照映射,如果關閉就把主頂點的光照結果疊加到輸出顔色中。後邊就是這個井ifdiff如果需要使用光照映射unt就會使用之前計算的光照紋理,采樣坐标對光照紋理進行采樣并解碼,得到光照紋理中的光照結果這部分代碼讀者可以在生成的代碼中找到這裡不再做飽腹。
如果如果沒有光照映射,這意味着他需要使用自定義的光照模型計算。這個是自定義的光照模型。
·而如果使用光照映射,用體會根據之前有光照紋理得到的結果,得到顔色值并疊加到輸出顔色c中。如果還開啟了動态光照畫中畫,用體還會計算對動态光照紋理的采樣結果,同樣把結果疊加到輸出顔色c中這部分。
·然後最後我們unity shader要用自定義的顔色修改函數對輸出顔色 c進行最後的修改。就是這樣傳回一個c,在這個代碼中unit 還使用了那隻紅unit sau queen 跟a player就是這個。
這一個來重置片狀圓的通透明通道。在預設情況下,所有不透明類型的表面着色器的透明通道都會被重置為一點零。而不管我們是否在光照函數中改變了它。
如上所述,如果我們想要保留它的透明通道,可以在表面着色器的編輯指令中添加keep keep up,保持透明。是以說到底forward pass就結束了接下來forward and pass和上面的forward pass基本類似,隻是簡代碼會更簡單一些。
最後一個重要的 pass 是山東casterpass,相對于之前的兩個 pass 的代碼更比較簡單膽小。短小它的生成原理也很簡單,就是通過調用自定義的頂點修改函數來保證計算陰影時使用的是和之前一緻的頂點坐标。
然後這些就是講了一個液體shader裡的表面着色器的實力的分析。
最後補充一下unity shader 的缺點。缺點主要是三點。
·第一:如果你需要和各種光源打交道,尤其是想要使用應體重的全局光照,你可能更喜歡使用表面着,但需要小心它的性能。
·第二:如果你需要處理的光源數目非常少,隻需要一盞平行光使用頂點偏遠着色器是更好的選擇。最重要的是如果你有很多自定義的渲染效果,請選擇頂點偏遠着色器,否則會非常非常的浪費。