Shader初學者的學習筆記
第一天 Unity Shader的結構
文章目錄
- Shader初學者的學習筆記
- 前言
- 一、Unity Shader結構
- 二、Unity Shader結構解析
- ① Properties
- ② Tags
- ③ RenderSetup(可選狀態)
- ④ Name
- ⑤ [Tags]
- ⑥ [RenderSetup]
- ⑦ 頂點著色器和片元著色器的代碼 (Unity最聰明的孩子)
- ⑧ Fallback
- 總結
前言
由于看完Unity Shader入門精要后發現自己看了就忘,于是想著寫博客來記錄一下入門精要這本書里面的我覺得需要記錄的內容,如果學的比較扎實的話,之后會對一些好的Shader進行學習,每天一篇
一、Unity Shader結構
Shader "Shader name"
{Properties{Name ("display name", propertyType) = DefaultValue ①}SubShader{[Tags] ②[RenderSetUp] ③Pass{[Name] ④[Tags] ⑤[RenderType] ⑥//頂點著色器和片元著色器 ⑦}}SubShader{...}FallBack "Diffuse" ⑧
}
二、Unity Shader結構解析
① Properties
Properties語義塊中包含了一系列的屬性,這些屬性會出現在材質面板中;
Name ("display name", PropertyType) = DefaultValue
EX:
//單獨的數字
_Int ("Int", Int) = 2
_Float ("Float", Float) = 1.5
_Range ("Range", Range(1.0, 5.0)) = 3.0
//四維向量
_Color ("Color", Color) = (1, 1, 1, 1)
_Vector ("Vector", Vector) = (2, 3, 6, 1);
//Textures 紋理類型的屬性定義稍微復雜,默認值嘶通過一個字符串后跟一個花括號來指定的,字符串里面要么是空,要么是內置的紋理名稱:white, black
_2D ("2D", 2D) = "" {}
_Cube ("Cube", Cube) = "white" {}
_3D ("3D", 3D) = "black" {}
Name:如果我們需要在Shader中訪問這些屬性,就需要使用各個屬性的名字;
display name則是出現在材質面板上的名字
PropertyType指定了屬性的類型
② Tags
Tags {"TagName1" = "Value1", "TagName2" = "Value2"}
標簽類型 | 說明 |
---|---|
Queue | 控制渲染順序,指定該物體屬于哪個渲染隊列,通過這種方式可以保證所有的透明物體可以在所有不透明物體的后面被渲染 |
RenderType | 對著色器進行分類,例如這是一個不透明的著色器,或是一個透明的著色器,這可以被用于著色器替換功能 |
DisableBatching | 一些SubShader在使用Unity的批處理功能時會出現問題,例如使用了模型空間下的坐標進行頂點動畫,這是可以通過該標簽來直接指明是否對該SubSahder使用批處理 |
ForceNoShadowCastingCasting | 控制使用該SubShader的物體是否會投射陰影 |
IgnoreProjector | 如果該標簽為True,那么使用該SubShader的物體將不會受Projector的影響,通常用于半透明物體 |
注意:以上的這些標簽之恩在SubShader中聲明,但是不能在Pass中聲明
③ RenderSetup(可選狀態)
狀態名稱 | 設置指令 | 解釋 |
---|---|---|
Cull | Cull Back /Front/ OFF | 設置剔除模式;剔除背面/正面/關閉剔除 |
ZTest | ZTest Less Greater/ LEqual? GEqual / NotEqual/ Always | 設置深度測試時使用的函數 |
ZWrite | ZWrite On / Off | 開啟/ 關閉深度寫入 |
Blend | Blend SrcFactor DscFactor | 開啟并設置混合模式 |
注意:如果在SubShader里面設置了渲染狀態后,將會應用到所有的Pass,如果我們不想這樣,可以在Pass語義塊中單獨進行上面的設置
④ Name
我們可以在Pass中單獨定義該Pass的名稱,通過這個名稱,我們可以使用UsePass命令來直接使用其他的Unity Shader中的Pass,但是需要注意的是:由于Unity內部會把所有的Pass的名稱轉化為大寫字母的表示.因此,使用UsePass命令時必須使用大寫形式的名字.
Ex:
UsePass "MyShader/MYPASSNAME
⑤ [Tags]
我們在上面說過,SubShader中的Tags與此處的標簽不同:此處的這些標簽也用于告訴渲染引擎我們希望怎樣渲染該物體
標簽類型 | 說明 |
---|---|
LightMode | 定義該Pass在Unity的渲染流水線中的角色 |
RquireOptions | 用于指定當滿足某些條件時才能渲染該Pass,它的值是一個用空格分隔的字符串 |
⑥ [RenderSetup]
我們在上面也說過,如果需要單獨設置每一個Pass的渲染狀態,就可以不用在SubShader中設置渲染狀態,例如:在進行雙面渲染時,我們希望在第一個Pass中剔除正面來對背面渲染,在第二個Pass中剔除背面來對正面進行渲染,這是就應該在Pass語義塊中進行單獨設置.因此這塊的狀態名稱與SubShader里面的狀態名稱是共用的.
⑦ 頂點著色器和片元著色器的代碼 (Unity最聰明的孩子)
在今天這一部分我們先不介紹頂點著色器和片元著色器,因為會在之后著重介紹,其實除了這兩個著色器之外,還有表面著色器等,由于我們在這本書中著重講的是頂點著色器和片元著色器,所以這塊就這樣寫.
頂點著色器要做的事情就是將在模型空間的頂點,先轉換到模型空間,在變換到觀察空間,經過裁剪空間的計算,對裁剪平面的圖元進行剔除,保留裁剪空間內的圖元.
一句話總結:
頂點著色器的最基本的任務就是把頂點坐標從模型空間轉換到裁剪空間中(逐頂點).
在片元著色器中,我們通常也可以得到該片元在屏幕空間的像素位置(逐片元).
⑧ Fallback
在每一個SubShader語義塊的后面,可以是一個Fallback命令,它用于告訴Unity,如果上面的所有SubShader在這塊顯卡上都不能運行,那么就用這個低級的shader吧!!!
事實上,Fallback還會影響陰影的投射,在渲染陰影紋理時,Unity會在每一個Unity Shader中尋找一個陰影投射的Pass,通常情況下,我們不需要自己專門實現一個Pass,這是因為Fallback使用的內置Shader中包含這樣一個通用的Shader,因此,為每一個Unity Shader正確設置Fallback是非常重要的.
總結
以上就是今天我總結的內容了,就是將Unity Shader的大致結構進行一個分析理解,方便之后對代碼的學習理解.