Unity高級開發(fā)(三)-Shader開發(fā)

01.png

1、什么是shader程序:

一段規(guī)定好輸入(顏色俐末,貼圖)丧鸯,輸出(渲染器能夠讀懂的點(diǎn)和顏色的對應(yīng)關(guān)系)的程序咧纠。

shader分類:
  • 1、表面著色器:
    為你做了大部分的工作秽澳,只需要簡單的技巧即可實(shí)現(xiàn)很多不錯(cuò)的效果闯睹。(本篇介紹這個(gè))
  • 2、片斷著色器:
    可以做的事情更多担神,比較難寫楼吃。
    使用片段著色器的主要目的是可以在比較低的層級上進(jìn)行更復(fù)雜(或者針對目標(biāo)設(shè)備更高效)的開發(fā)。

2妄讯、shader的結(jié)構(gòu):

著色器:本身就是一段代碼孩锡,專業(yè)性非常強(qiáng)的代碼。就是指著色器有哪些輸入捞挥。這些子著色器由運(yùn)行的平臺(tái)選擇浮创。它包含:1.屬性定義、2.多個(gè)或者至少一個(gè)子著色器砌函、3.還有一個(gè)處理后的結(jié)果即回滾斩披。而回滾就是計(jì)算著色時(shí),用來處理所有的子著色器不能運(yùn)行的情況讹俊。

3垦沉、關(guān)于Shader腳本

3-1、創(chuàng)建一個(gè)自己的shader腳本
02.png
3-2仍劈、如何選擇我們創(chuàng)建的shader
04.png

4厕倍、shader腳本介紹

03.png
4-1、Properties : 屬性
05.png
  • 數(shù)值和范圍
name(“display name”, Range(min,max)) = number
name(“display name”, Float) = number
name(“display name”, Int) = number
name("display name", Rect) = "name"{ options }

這些定義一些數(shù)值屬性贩疙,每個(gè)等號后面表示默認(rèn)的取值讹弯,name是給開發(fā)者給這個(gè)值起的可以在代碼中訪問的名字况既,display name則是在材質(zhì)面板上顯示的名字

  • 顏色和向量
name(“display name”,Color) = (number,number,number,number)
name(“display name”, Vector) =  (number,number组民,number,number)

定義顏色值RGBA和向量值(xyzw),在Shader的數(shù)學(xué)中棒仍,是一樣的。Color會(huì)在屬性面板上出現(xiàn)一個(gè)可供用戶使用的調(diào)色面板按鈕臭胜。Vector則是在面板上出現(xiàn)可以填寫數(shù)字的欄

  • 貼圖
name(“display name”, 2D) = number
name(“display name”, Cube) = number
name(“display name”, 3D) = number
 // 后面texGen 是紋理生成模式(ObjectLinear , SphereMap莫其,CubeReflect,CubeNormal)耸三,一般自定義的shader不會(huì)使用這些模式
name(“display name”, 3D) = "white"{ texGen Eyeliner }

定義2D貼圖乱陡,CubeMap和3D貼圖,等號后面都是默認(rèn)的圖仪壮,都是空字符串或者是Unity定義的“white”,"black","gray","bump".

  • 補(bǔ)充
    Unity內(nèi)定的一些屬性列表:
    [HideInInspector] 不顯示對應(yīng)的屬性值
    [NoScaleOffset] 默認(rèn)貼圖面板帶有tiling和offset屬性憨颠,這個(gè)讓它們不顯示
    [Normal] 該帖圖放進(jìn)來是法線圖
    [HDR] 該帖圖期望是HDR的圖 ,HDR:高動(dòng)態(tài)光照渲染(High-Dynamic Range睛驳,簡稱HDR)圖像
4-2烙心、SubShader - 子著色器的實(shí)現(xiàn)

一個(gè)Shader中可以有多個(gè)SubShader(子著色器)實(shí)現(xiàn),子著色器定義了一個(gè)渲染通道的列表乏沸,并可選是否為所有通道初始化所需要的通用狀態(tài)淫茵。

SubShader
{
    Cull off // 雙面顯示
Blend One One
     Tags{"TagName1" = "Value1"
              "TagName2" = "Value2"
        }
  // 每一個(gè)SubShader必須要有一個(gè)Pass,可以有多個(gè)Pass,用來控制被渲染的幾何體對象
  Pass{   // Pass里面就是整段渲染過程的實(shí)現(xiàn)
     
        }
}
  • RenderState 渲染狀態(tài)
    通道設(shè)置顯示硬件的各種狀態(tài)蹬跃,例如能打開alpha混合匙瘪,使用霧等
    Cull off/Back/Front // 雙面顯示/背面不顯示/正面不顯示
    設(shè)置多邊形剔除模式
    ZTest(Less/Greater/LEqual/GEqual/Equal/NotEqual/Always)默認(rèn)Lequal
    設(shè)置深度寫模式,是否次物體的像素深度會(huì)被記錄(默認(rèn)記錄)蝶缀,半透明物體默認(rèn)不記錄
    ZWrite On/off
    開啟alpha測試
    AlphaTest(Less/Greater/LEqual/GEqual/Equal/NotEqual/Always)
    設(shè)置alpha混合模式 ()
    Blend SourceBlendMode DestBlendMode
    • Blend SourceBlendMode DestBlendMode 混合模式

image.png
  • Fog{ Fog Block} 設(shè)置霧參數(shù)
    Fog{Fog Commands}
    Mode Off/Global/Linear/Exp/Exp2
    Color ColorValue
    Density FloatValue
    Range FloatValue
fog{
  Mode Linear
  Color(1,1,1,1)
  Density 1000
}

RenderState

  • ColorMask RGB/A/0 設(shè)置顏色遮罩丹喻,0就是關(guān)閉所有顏色通道的渲染

  • Offset offsetFactor ,offsetUnits ,設(shè)置深度偏移

  • Color Color value 設(shè)置當(dāng)頂點(diǎn)關(guān)照關(guān)閉時(shí)所使用的顏色

  • SeparateSpecular On/Off 開啟或關(guān)閉頂點(diǎn)光照相關(guān)的平行高光顏色

  • ColorMaterial/AmbientAndDiffuse/Emission 當(dāng)計(jì)算頂點(diǎn)光照時(shí)使用頂點(diǎn)顏色翁都。

  • Material{Material Block} 定義一個(gè)使用頂點(diǎn)光照管線的材質(zhì)

  • Lighting On/Off 開啟或關(guān)閉頂點(diǎn)光照

  • Tags 標(biāo)簽
    標(biāo)簽主要是告訴硬件什么時(shí)候調(diào)用該著色器碍论,比如操作手冊,2:30后執(zhí)行什么步驟柄慰,這就是標(biāo)簽鳍悠。

    • 標(biāo)簽屬性

      • 1:Rendering Order - Queue tag : 渲染隊(duì)列,就是渲染順序
        • Queue有四種選擇
          1-Background : 最早被調(diào)用坐搔,用來渲染天空盒或者背景
          2-Geometry : 默認(rèn)值藏研,用來渲染非透明物體(普通情況下,場景中的大部分物體就是非透明的)
          3-Transparent :用于渲染透明物體(從后往前的順序渲染)
          4-Overlay : 最后渲染概行,用來渲染疊加效果(如鏡頭光暈等)
    • 2:RenderType tag : 渲染類型 主要告訴系統(tǒng)什么類型要怎么顯示蠢挡?
      Opaque: 不透明,最常用(帶法線貼圖的,自發(fā)光的,反射业踏,地形)
      Transparent:半透明物體(粒子禽炬,字體)
      TransparentCutout:透明遮罩shader
      Background:天空Shaders
      Overlay:GUITexture,Helo,Flare shaders
      TreeOpaque:枝干
      TreeTransparentCutout:樹葉
      TreeBillboard: 樹的面片,效果會(huì)好一些
      Grass:草
      GrassBillboard:草的面片

    • 3:其他標(biāo)簽
      ForceNoShadowCasting tag 不產(chǎn)生陰影
      IgnoreProjector tag 不被Projectors影響


      06.png

我們在Unity中可以通過相機(jī)方法:
RenderWithShader Render the camera with shader replacement.設(shè)置渲染shader
SetReplacementShader Make the camera render with shader replacement. 設(shè)置渲染替換shader

4-3勤家、SubShader - LOD 著色器的設(shè)定值

LOD:調(diào)整根據(jù)設(shè)備圖形性能來調(diào)整畫質(zhì)時(shí)可以進(jìn)行比較精確的控制瞎抛。

07.png
關(guān)于
VertexLit及其系列 = 100
Decal, Reflective VertexLit = 150
Diffuse = 200
Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
Bumped, Specular = 300
Bumped Specular = 400
Parallax = 500
Parallax Specular = 600

如何進(jìn)行質(zhì)量設(shè)定?
http://www.ceeger.com/Components/class-QualitySettings.html

4-4却紧、Input

Input其實(shí)是需要我們?nèi)ザx的結(jié)構(gòu),這給我們提供了一個(gè)機(jī)會(huì)胎撤,可以把所需要參與計(jì)算的數(shù)據(jù)都放到這個(gè)Input結(jié)構(gòu)中晓殊,傳入surf函數(shù)使用;


16.png

UV mapping的作用是將一個(gè)2D貼圖上的點(diǎn)按照一定規(guī)則映射到3D模型上伤提,是3D渲染中最常見的一種頂點(diǎn)處理手段巫俺。
變量前面加一個(gè)uv_MainTex:
就代表提取它的uv值(其實(shí)就是兩個(gè)代表貼圖上點(diǎn)的二維坐標(biāo) ), surf程序中直接通過訪問uv_MainTex來取得這張貼圖當(dāng)前需要計(jì)算的點(diǎn)的坐標(biāo)值了

4-5、surf
21.png

SurfaceOutput是已經(jīng)定義好了里面類型輸出結(jié)構(gòu)肿男,但是一開始的時(shí)候內(nèi)容暫時(shí)是空白的介汹,我們需要向里面填寫輸出,這樣就可以完成著色了舶沛。先仔細(xì)看看INPUT吧嘹承,現(xiàn)在可以跳回來看上面定義的INPUT結(jié)構(gòu)體了:

17.png
4-6、FallBack
Fallback Off    明確表示沒有后援的shader
Fallback "name" 指定后援名字

4-7如庭、Pass(通道)

Pass{[Name and Tags] [RenderSetup][TextureSetup]}
Pass{[名字和設(shè)定標(biāo)簽][渲染設(shè)定][貼圖設(shè)定]}
SubShader里面的Tags是針對SubShader進(jìn)行設(shè)定叹卷,而這里面的Tags是針對Pass(通道)做一些設(shè)定

  • Tags 用來控制光照管道(環(huán)境光照,頂點(diǎn)光照和像素光照)中Pass的任務(wù)和一些其他選項(xiàng)坪它。
    LightMode tag 光照模式標(biāo)簽
    Always:總是渲染骤竹,沒有光照應(yīng)用
    ForwardBase:用于正向渲染,環(huán)境主要方向燈和電光/SH等的應(yīng)用
    ForwardAdd:用于正向渲染往毡,附加的像素光被應(yīng)用蒙揣,每個(gè)光照一個(gè)Pass
    PrepassBase:用于延遲光照,渲染法線/鏡面指數(shù)
    PrepassFinal:用于延遲光照开瞭,通過結(jié)合紋理懒震,光照和自發(fā)光渲染最終顏色。
    Vertex:用于頂點(diǎn)光照渲染惩阶,當(dāng)物體沒有光照映射時(shí)挎狸,所有頂點(diǎn)光照被應(yīng)用
    VertexLMRGBM:用于頂點(diǎn)光照渲染,當(dāng)物體有光照映射的時(shí)候使用頂點(diǎn)光照渲染断楷。
    VertexLM:用于頂點(diǎn)光照渲染锨匆,當(dāng)物體有光照映射的時(shí)候使用頂點(diǎn)光照渲染
    ShadowCaster:將物體當(dāng)作陰影產(chǎn)生者來渲染
    ShadowCollector:正向渲染對象的路徑,將對象陰影收集到屏幕空間緩沖區(qū)中。

頂點(diǎn)著色器與片段著色器所有的代碼要寫在CGPROGRAM 與 ENDCG里面,頂點(diǎn)著色器返回的就是一個(gè)頂點(diǎn)信息恐锣,而像素著色器返回的就是一個(gè)Color值

Pass{
CGPROGRAM
#pragma vertex vert   //預(yù)編譯指令 表示是一個(gè)頂點(diǎn)光照的名字茅主, vert是頂點(diǎn)光照方法的名字,下方的代碼有這個(gè)函數(shù)
#pragma fragment frag // 預(yù)編譯指令土榴,表示是一個(gè)片段著色器名字诀姚,frag是片段著色器方法的名字,下面有這個(gè)函數(shù)的實(shí)現(xiàn)
ENDCG
}
  • 預(yù)編譯指令

08.png

為什么再次申明這個(gè)屬性:
我們用來實(shí)例的這個(gè)shader其實(shí)是由兩個(gè)相對獨(dú)立的塊組成的玷禽,外層的屬性聲明赫段,回滾等等是Unity可以直接使用和編譯的ShaderLab;而現(xiàn)在我們是在CGPROGRAM...ENDCG
這樣一個(gè)代碼塊中矢赁,這是一段CG程序糯笙。對于這段CG程序,要想訪問在Properties
中所定義的變量的話撩银,必須使用和之前變量相同的名字進(jìn)行聲明给涕。于是其實(shí)sampler2D _MainTex;
做的事情就是再次聲明并鏈接了_MainTex,使得接下來的CG程序能夠使用這個(gè)變量额获。

  • Pragma Target 2.0 與Target 3.0,Target 3.5的區(qū)別
    如果想讓我們寫的著色器代碼在不同的GPU運(yùn)行够庙,那么使用2.0就好,這是通用的。
#pragma target 2.0
Works on all platforms supported by Unity. DX9 shader model 2.0.
Limited amount of arithmetic & texture instructions; 8 interpolators; no vertex texture sampling; no derivatives in fragment shaders; no explicit LOD texture sampling.

較高的著色器編譯目標(biāo)允許使用更現(xiàn)代的GPU功能
具體參考文檔Unity User Manual (5.6)/Graphics/Graphics Reference/Shader Reference/Writing vertex and fragment shaders/Shader Compilation Target Levels
Unity跨平臺(tái)中抄邀,Shader可以通過根據(jù)平臺(tái)來進(jìn)行耘眨,不指定那么就會(huì)支持所有平臺(tái)

image.png

屬性中的Color和Vector對應(yīng)CG中的float4類型
屬性中的Range和Float對應(yīng)CG中的Float類型
屬性中的2D紋理對應(yīng)CG中Sampler2D類型
屬性中的CUBE和Rect紋理對應(yīng)CG中SamplerCUBE 和 Sampler RECT類型
頂點(diǎn)數(shù)據(jù)的獲取:
appdata_base :包含頂點(diǎn)位置撤摸,法線和紋理坐標(biāo)
appdata_tan:包含頂點(diǎn)位置毅桃,切線,法線和紋理坐標(biāo)
appdata_full:包含頂點(diǎn)位置准夷,法線钥飞,兩張貼圖和紋理坐標(biāo),頂點(diǎn)顏色

Name    Value
UNITY_MATRIX_MVP    Current model * view * projection matrix. // 模型坐標(biāo)系 * 觀察坐標(biāo)系 * 投影坐標(biāo)系
UNITY_MATRIX_MV Current model * view matrix.
UNITY_MATRIX_V  Current view matrix.
UNITY_MATRIX_P  Current projection matrix.
UNITY_MATRIX_VP Current view * projection matrix.
UNITY_MATRIX_T_MV   Transpose of model * view matrix.
UNITY_MATRIX_IT_MV  Inverse transpose of model * view matrix.
_Object2World   Current model matrix.
_World2Object   Inverse of current world matrix.

5衫嵌、參考文檔

https://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html
https://onevcat.com/2013/08/shader-tutorial-2/
http://www.tuicool.com/articles/JvYJ3em
http://www.itnose.net/detail/6143450.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末读宙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子楔绞,更是在濱河造成了極大的恐慌结闸,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酒朵,死亡現(xiàn)場離奇詭異桦锄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蔫耽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門结耀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事图甜“啵” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵黑毅,是天一觀的道長嚼摩。 經(jīng)常有香客問我,道長矿瘦,這世上最難降的妖魔是什么枕面? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮缚去,結(jié)果婚禮上膊畴,老公的妹妹穿的比我還像新娘。我一直安慰自己病游,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布稠通。 她就那樣靜靜地躺著衬衬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪改橘。 梳的紋絲不亂的頭發(fā)上滋尉,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機(jī)與錄音飞主,去河邊找鬼狮惜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛碌识,可吹牛的內(nèi)容都是我干的碾篡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼筏餐,長吁一口氣:“原來是場噩夢啊……” “哼开泽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起魁瞪,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤穆律,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后导俘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體峦耘,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年旅薄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辅髓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖利朵,靈堂內(nèi)的尸體忽然破棺而出律想,到底是詐尸還是另有隱情,我是刑警寧澤绍弟,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布技即,位于F島的核電站,受9級特大地震影響樟遣,放射性物質(zhì)發(fā)生泄漏而叼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一豹悬、第九天 我趴在偏房一處隱蔽的房頂上張望葵陵。 院中可真熱鬧,春花似錦瞻佛、人聲如沸脱篙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绊困。三九已至,卻和暖如春适刀,著一層夾襖步出監(jiān)牢的瞬間秤朗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工笔喉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留取视,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓常挚,卻偏偏與公主長得像作谭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子奄毡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容