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腳本
3-2仍劈、如何選擇我們創(chuàng)建的shader
4厕倍、shader腳本介紹
4-1、Properties : 屬性
- 數(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 混合模式
- 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 : 最后渲染概行,用來渲染疊加效果(如鏡頭光暈等)
- Queue有四種選擇
- 1:Rendering Order - Queue tag : 渲染隊(duì)列,就是渲染順序
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)行比較精確的控制瞎抛。
關(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ù)使用;
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
SurfaceOutput是已經(jīng)定義好了里面類型輸出結(jié)構(gòu)肿男,但是一開始的時(shí)候內(nèi)容暫時(shí)是空白的介汹,我們需要向里面填寫輸出,這樣就可以完成著色了舶沛。先仔細(xì)看看INPUT吧嘹承,現(xiàn)在可以跳回來看上面定義的INPUT結(jié)構(gòu)體了:
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ù)編譯指令
為什么再次申明這個(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)
屬性中的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