UnityShader 基礎知識

Unity一共提供了4 種Unity Shader 模板供我們選擇——
Standard Surface Shader:包含了標準光照模型基于物理的渲染方法表面著色器模板 (PBR)
Unlit Shader:一個不包含光照(但包含霧效)的基本的頂點/片元著色器
Image Effect Shader: 實現各種屏幕后處理效果
Compute Shader:利用GPU 的并行性來進行一些與常規渲染流水線無關的計算(GPU Skinning?) ps:(http://docs.unity3d.con/Manual/ComputeShaders.html)

ShaderLab

是Unity 提供的編寫Unity Shader 的一種說明性語言。它使用了一些嵌套在花括號內部的語義(syntax ) 來描述一個Unity Shader 文件的結構。

Shader ” ShaderName” {
    Properties {
        //屬性
            Name (”display name", PropertyType) = DefaultValue
//一個字符串后跟一個花括號來指定的,其中,字符串要么是空的,要么是內置的紋理名稱,如“white "“ black ”“ gray "或者“ bump ”。
_Cube(”Cube ” , Cube ) = ”white”{}
    }
    SubShader {
        //顯卡A使用的子著色器
//真正意義上的Shader 代碼會出現在這里
        //表面著色器(Surface Shader )或者
        // 頂點/片元著色器( Vertex/Fragment Shader )或者
        //固定函數著色器( Fixed Function Shader )

              //可選的 標簽
              
          [Tags]  
          //可選的 狀態
          [RenderSetup]
          Pass {
             // 例如 /只有定義了正確的LightMode,我們才能得到一些Unity 的內置光照變量
            Tags { "LightMode"="ForwardBase" }
              // /
               //   CGPROGRAM和ENDCG 來包圍CG 代碼片
            
                //為了使用Properties語義塊中的屬性,需要定義一個和該屬性相同的變量類似c#
                fixed4 _Diffuse;
          }
          // Other Passes
     }
    SubShader {
        //顯卡B使用的子著色器
    ]   
    Fallback ”VertexLit”

ShaderLab 中常見的渲染狀態設置選項。


image

將會應用到所有的Pass。如果我們不想這樣(例如在雙面渲染中,我們希望在第一個Pass 中剔除正面來對背面進行渲染,在第二個Pass 中剔除背面來對正面進行渲染),可以在Pass 語義塊中單獨進行上面的設置。

標簽
SubShader 的標簽( Tags )是一個鍵值對(Key/Value Pair )。用來告訴Unity 的渲染引擎: SubShader我希望怎樣以及何時渲染這個對象。


image

Pass 語義塊

Pass 語義塊包含的語義如下:

Pass {
    [Name]
    [Tags]
    [RenderSetup]
    // Other code
}
//可以在Pass 中定義該Pass 的名稱
Name "MyPassName"
//通過這個名稱,我們可以使用ShaderLab 的UsePass 命令來直接使用其他Unity Shader 中的Pass
// 內部會把所有Pass 的名稱轉換成大寫字母的表示
UsePass "MyShader/MYPASSNAME”
image

-UsePass:如我們之前提到的一樣,可以使用該命令來復用其他Unity Shader 中的Pass;
-GrabPass:該Pass 負責抓取屏幕并將結果存儲在一張紋理中,以用于后續的Pass 處理

Fallback

最后保底的渲染方式,以上都不執行的話。
其中還包括陰影投射

shader種類的選擇

  • 如果你想和各種光源打交道,你可能更喜歡使用表面著色器, 但需要小心它在移動平臺的性能表現。
    -如果你需要使用的光照數目非常少, 例如只有一個平行光, 那么使用頂點/片元著色器是一個更好的選擇。
    -最重要的是,如果你有很多自定義的渲染效果, 那么請選擇頂點/片元著色器。

渲染流水線

應用階段(Application Stage )、幾何階段( Geometry Stage )、光柵化階段( Rasterizer Stage )
image

幾何階段

幾何階段用于處理所有和我們要繪制的幾何相關的事情。例如,決定需要繪制的圖元是什么,怎樣繪制它們,在哪里繪制它們。這一階段通常在GPU 上進行。
幾何階段負責和每個渲染圖元打交道,進行逐頂點、逐多邊形的操作。這個階段可以進一步分成更小的流水線階段,這在下一章中會講到。幾何階段的一個重要任務就是把頂點坐標變換到屏幕空間中,再交給光柵器進行處理。通過對輸入的渲染圖元進行多步處理后,這一階段將會輸出屏幕空間的二維頂點坐標、每個頂點對應的深度值、著色等相關信息,并傳遞給下一個階段。

光柵化階段

這一階段將會使用上個階段傳遞的數據來產生屏幕上的像素,并渲染出最終的圖像。這一階段也是在GPU 上運行。光柵化的任務主要是決定每個渲染圖元中的哪些像素應該被繪制在屏幕上。它需要對上一個階段得到的逐頂點數據(例如紋理坐標、頂點顏色等〉進行插值,然后再進行逐像素處理。
和上一個階段類似,光柵化階段也可以分成更小的流水線階段

什么是渲染狀態呢? 一個通俗的解釋就是,這些狀態定義了場景中的網格是怎樣被渲染的

幾何階段和光柵化階段可以分成若干更小的流水線階段, 這些流水線階段由GPU 來實現, 每個階段GPU 提供了不同的可配置性或可編程性。圖中展示了不同的流水線階段以及它們的可配置性或可編程性。

image

-頂點著色器( Vertex Shader ) 是完全可編程的,它通常用于實現頂點的空間變換、頂點著色等功能。
-曲面細分著色器( Tessellation Shader ) 是一個可選的著色器,它用于細分圖元。
-幾何著色器( Geometry Shader ) 同樣是一個可選的著色器,它可以被用于執行逐圖元( Per-Primitive)的著色操作,或者被用于產生更多的圖元。下一個流水線階段是
-裁剪( Clipping ),這一階段的目的是將那些不在攝像機視野內的頂點裁剪掉,并剔除某些三角圖元的面片。這個階段是可配置的。

例如,我們可以使用自定義的裁剪平面來配置裁剪區域,也可以通過指令控制裁剪三角圖元的正面還是背面。幾何概念階段的最后一個流水線階段是屏幕映射( Screen Mapping ) 。這一階段是不可配置和編程的,它負責把每個圖元的坐標轉換到屏幕坐標系中。
光柵化概念階段中的三角形設置(Triangle Setup ) 和三角形遍歷( Triangle Traversal )階段也都是固定函數(Fixed-Function )的階段。接下來的
片元著色器(Fragment Shader ),則是完全可編程的,它用于實現逐片元( Per-Fragment )的著色操作。最后,
逐片元操作( Per-Fragment Operations ) 階段負責執行很多重要的操作,例如修改顏色、深度緩沖、進行混合等,它不是可編程的,但具有很高的可配置性。

頂點著色器

我們可以通過改變頂點位置來模擬水面、布料等
最基本的頂點著色器必須完成的一個工作是,把頂點坐標從模型空間轉換到齊次裁剪空間。想想看, 我們在頂點著色器中是不是會看到類似下面的代碼:

o.pos = mul(UNITY_MVP, v.position);

屏幕映射

把每個圖元的x 和y 坐標轉換到屏幕坐標系(Screen Coordinates ) 下
這個過程實際是一個縮放的過程, 如圖2.10 所示。你可能會問,那么輸入的z 坐標會怎么樣呢?屏幕映射不會對輸入的z 坐標做任何處理。實際上,屏幕坐標系和z 坐標一起構成了一個坐標系,叫做窗口坐標系( Window Coordinates )。這些值會一起被傳遞到光柵化階段。

逐片元操作

image
image

模板測試( Stencil Test )
模板測試通常用于限制渲染的區域。另外,模板測試還有一些更高級的用法, 如渲染陰影、輪廓渲染等。
深度測試(Depth Test)
通常這個比較函數是小于等于的關系,即如果這個片元的深度值大于等于當前深度緩沖區中的值,那么就會舍棄它。這是因為,我們總想只顯示出離攝像機最近的物體,而那些被其他物體遮擋的就不需要出現在屏幕上。如果一個片元沒有通過深度測試,它就沒有權利更改深度緩沖區中的值。而如果它通過了測試,開發者還可以指定是否要用這個片元的深度值覆蓋掉原有的深度值, 這是通過開啟/關閉深度寫入來做到的。透明效果和深度測試以及深度寫入的關系非常密切。
片元通過上面測試,它就可以自豪地來到合并功能的面前。為什么需要合并?我們要知道,這里所討論的渲染過程是一個物體接著一個物體畫到屏幕上的。而每個像素的顏色信息被存儲在一個名為顏色緩沖的地方。因此,當我們執行這次渲染時,顏色緩沖中往往已經有了上次渲染之后的顏色結果,那么, 我們是使用這次渲染得到的顏色完全覆蓋掉之前的結果,還是進行其他處理?這就是合并需要解決的問題。
對于不透明物體,開發者可以關閉混合(Blend )操作。這樣片元著色器計算得到的顏色值就會直接覆蓋掉顏色緩沖區中的像素值。但對于半透明物體,我們就需要使用混合操作來讓這個物體看起來是透明的。

image

各種測試的順序是可以改變的 不一定非要片元之后再計算深度等等。


image
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評論 6 540
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,275評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,904評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,368評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,736評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,919評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,481評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,235評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,427評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,656評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,160評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,380評論 2 379