一愿卒、著色器基礎(chǔ)
1.什么是著色器,簡(jiǎn)介
著色器(Shader)咖刃,是一款運(yùn)行在GPU->Graphic Processor Unit上的程序化漆,其可以給開(kāi)發(fā)人員提供直接操控硬件設(shè)備(顯卡)的能力。Unity絕大多數(shù)渲染工作都是通過(guò)Shader來(lái)完成的殊轴。材質(zhì)都是使用Shader來(lái)渲染的衰倦,定義不同的材質(zhì)就是在選擇不同的Shader。材質(zhì)就是對(duì)紋理進(jìn)行GPU編程加工旁理。
2.Unity3D著色器的優(yōu)勢(shì)
在實(shí)際開(kāi)發(fā)中樊零,很多的特效鏡面反射和折射,動(dòng)物毛發(fā)孽文,卡通效果等都通過(guò)著色器來(lái)渲染驻襟。如果使用CPU來(lái)處理的話,計(jì)算量非常大芋哭,編程難度高沉衣,GPU就可以很簡(jiǎn)單的高效的完成這個(gè)工作。
3.主流的針對(duì)GPU編程的技術(shù):
a.HLSL(High Level Shading Language)微軟研發(fā)的楷掉,只能供Direct3D使用厢蒜,只能跑在微軟旗下的設(shè)備上。
b.GLSL(OpenGL Shading Language)可以全平臺(tái)通用
c.CG(C for Graphics)NVIDIA和微軟合作開(kāi)發(fā)的烹植,獨(dú)立于三維編程接口的斑鸦,即不依賴于D3D或OpenGL,可以和這兩種圖形渲染庫(kù)結(jié)合起來(lái)使用草雕,使用類(lèi)似于C語(yǔ)言的方式編寫(xiě)一次程序便可以跨平臺(tái)運(yùn)行巷屿。
4.Unity的著色語(yǔ)言:
為了實(shí)現(xiàn)跨平臺(tái),Unity對(duì)自身的著色語(yǔ)言的選型重點(diǎn)還是偏向支持CG語(yǔ)言墩虹,Unity自己定義了一個(gè)著色器語(yǔ)言叫ShaderLab來(lái)針對(duì)不同的GPU和平臺(tái)開(kāi)發(fā)游戲嘱巾。
特點(diǎn):編寫(xiě)一次代碼憨琳,會(huì)根據(jù)具體的平臺(tái)不同而進(jìn)行相應(yīng)平臺(tái)的API的編譯。
二旬昭、Unity著色器ShaderLab的基礎(chǔ)語(yǔ)法結(jié)構(gòu):
1.Shader
著色器的程序根命令篙螟,每個(gè)著色器都必須定義唯一一個(gè)Shader,其中主要定義了材質(zhì)如何使用這個(gè)著色器對(duì)象问拘。
Shader "name"
{
[Properties] //屬性
Subshaders{...} //子著色器
[Fallback] //降級(jí)著色器
}
其中name為著色器的名字遍略。
其中涉及到的幾個(gè)部分的順序不能打亂,要嚴(yán)格按照順序編寫(xiě)著色器骤坐。
[]中的內(nèi)容代表為可選內(nèi)容绪杏,也就是說(shuō)可以沒(méi)有。屬性和降級(jí)可以不寫(xiě)纽绍,但是子著色器必須有蕾久。
2.Properties
代表的是著色器中使用到的所有屬性,著色器可以在屬性塊中定義一些屬性參數(shù)拌夏,這些參數(shù)可以在Inspector中進(jìn)行編輯和調(diào)整僧著,[Properties]塊就是用來(lái)定義這些參數(shù)的。Properties{屬性塊}
示例語(yǔ)法:
name("display name", Range(min, max)) = num 定義了一個(gè)浮點(diǎn)數(shù)的范圍
name("display name", Float) = num 定義了一個(gè)浮點(diǎn)數(shù)
name("display name", Int) = num 定義了一個(gè)整型數(shù)
name("display name", Color) = (num, num, num, num) 定義了一個(gè)顏色值辖佣,0<=num<=1
name("display name", Vector) = (num, num, num, num) 定義了一個(gè)四維向量值
name("display name", 2D) = "name"{options} 定義了一個(gè)2D紋理屬性
name("display name", Rect) = "name"{options} 定義了一個(gè)矩形紋理屬性
name("display name", Cube) = "name"{options} 定義了一個(gè)立方體貼圖紋理屬性
name("display name", 3D) = "name"{options} 定義了一個(gè)3D紋理屬性
實(shí)際案例:
Properties
{
_RangeValue("Range Value", Range(0.1, 0.5)) = 0.3
_FloatValue("Float Value", Float) = 1.5
_Color("Color", Color) = (1, 1, 1, 1)
_Vector("Vector", Vector) = (1, 1, 1, 1)
_MainTex("Albedo(RGB)", 2D) = "white"{TexGen EyeLinear}
_Cube("CubeTex", Cube) = "skybox"{TexGen CubeReflect}
}
3.Subshader
真正用于呈現(xiàn)渲染物體的代碼都放在子著色器中霹抛。
每一個(gè)Shader都包含一個(gè)Subshader列表,游戲運(yùn)行時(shí)會(huì)根據(jù)實(shí)際的運(yùn)行環(huán)境從上到下選擇一個(gè)合適的Subshader來(lái)使用卷谈。
SubShader{[Tags] [CommonState] Pass{}}
子著色器由可選標(biāo)簽杯拐,通用狀態(tài)以及一個(gè)通道列表構(gòu)成。
定義通道的類(lèi)型有RegularPass世蔗,UsePass端逼,GrabPass。
在通道中定義的狀態(tài)對(duì)整個(gè)子著色器都可見(jiàn)污淋,也就說(shuō)所有的通道都共享一組狀態(tài)顶滩。
示例語(yǔ)法:
SubShader
{
Tags {"Queue" = "Transparent"} //設(shè)置渲染隊(duì)列標(biāo)簽值為透明隊(duì)列
Pass {
Lighting off //關(guān)閉光照
SetTexture[_MainTex]{} //設(shè)置主紋理屬性
}
}
4.SubShader常用標(biāo)簽(Tags)
子著色器使用標(biāo)簽(Tags)來(lái)告訴Unity渲染引擎或者其他用戶如何認(rèn)證這個(gè)SubShader。
Tags基本語(yǔ)法如下:
Tags{"標(biāo)簽1" = "值1" "標(biāo)簽2" = "值2"}
其中每一個(gè)標(biāo)簽都是由一組鍵值對(duì)(key/value pair)組成寸爆,常用的有以下幾種:
(1)Queue礁鲁,隊(duì)列標(biāo)簽,用來(lái)決定對(duì)象被渲染的次序赁豆。其中有5種預(yù)定義的可選值仅醇,分別為:
Background->1000;Geometry(默認(rèn)值)->2000;AlphaTest->2450;Transparent->3000;Overlay->4000
(2)中間值,使用中間值隊(duì)列來(lái)滿足一些特定的需求魔种。把隊(duì)列值當(dāng)成一個(gè)整型值來(lái)對(duì)待析二,那么就可以給出如下的隊(duì)列:
Tags {"Queue" = "Geometry + 600"} //隊(duì)列值為Geometry + 600,即2600,在AlphaTest和Transparent之間
(3)RenderType叶摄,渲染類(lèi)型標(biāo)簽属韧,將著色器分為若干個(gè)預(yù)定義組,RenderType只能從預(yù)設(shè)值中取一個(gè)蛤吓,不能是其他的值宵喂。
例如采用透明著色器就無(wú)法使用Alpha測(cè)試著色器。
5.Pass通道
SubShader包裝了一個(gè)渲染方案柱衔,這個(gè)方案是由一個(gè)個(gè)通道來(lái)執(zhí)行的樊破。
一個(gè)SubShader可以包含多個(gè)Pass塊,每個(gè)Pass都能使幾何對(duì)象被渲染一次唆铐。語(yǔ)法如下:
Pass{[Name and Tags] [RenderSetup] [TextureSetup]}
RenderSetup可以設(shè)置顯卡的各種狀態(tài),例如:
Lighting 光照 開(kāi)啟或關(guān)閉光照奔滑,開(kāi)關(guān)狀態(tài)值為On或Off
Material{材質(zhì)塊} 材質(zhì) 定義一個(gè)使用頂點(diǎn)光照管線的材質(zhì)
ColorMaterial 顏色材質(zhì) 當(dāng)計(jì)算頂點(diǎn)光照時(shí)使用頂點(diǎn)顏色艾岂,可以是AmbientAndDiffuse或Emission
SeparateSpecular 開(kāi)關(guān)狀態(tài) 開(kāi)啟或關(guān)閉頂點(diǎn)光照相關(guān)的鏡面高光顏色,開(kāi)關(guān)的值為On或Off
Color 顏色 設(shè)置當(dāng)頂點(diǎn)光照關(guān)閉時(shí)所使用的顏色
Fog{霧塊} 霧 設(shè)置霧的參數(shù)
AlphaTest Alpha測(cè)試 默認(rèn)值為L(zhǎng)Equal
6.Fallback
降級(jí)著色器必須定義在所有子著色器之后朋其。代表如果沒(méi)有任何子著色器能夠運(yùn)行在當(dāng)前設(shè)備上王浴,就會(huì)嘗試使用這個(gè)降級(jí)著色器。
語(yǔ)法格式:
Fallback "著色器名" -> 退回到指定名稱的著色器
Fallback off -> 顯示的告訴GPU沒(méi)有相關(guān)的降級(jí)著色器可用梅猿,并且也不會(huì)打印任何的警告信息氓辣。
7、SetTexture的具體寫(xiě)法:
SetTexture [貼圖名稱]
{
ConstantColor color
Combine ColorPart, AlphaPart
}
其中Combine部分是可選的袱蚓,作用是設(shè)定顏色部分和透明部分的疊加方式钞啸。
其中ConstantColor color
定義一個(gè)常量顏色在Combine指令里面使用
其中Combine命令是指
一般的寫(xiě)法是Combine texture * primary,這樣的意思是把貼圖乘以頂點(diǎn)顏色作為最終顏色喇潘。
也可以寫(xiě)成Combine texture * primary DOUBLE体斩,加一個(gè)DOUBLE的作用是讓光照強(qiáng)度增幅成2倍。primary代表的是初始的頂點(diǎn)顏色颖低,也就是在沒(méi)有加貼圖之前的頂點(diǎn)顏色絮吵。