[解讀Unity中的CG編寫(xiě)Shader系列1——初識(shí)CG]
CG=C for Graphics 用于計(jì)算機(jī)圖形編程的C語(yǔ)言超集
前提知識(shí)點(diǎn):
1.CG代碼必須用
CGPROGRAM
。。。
ENDCG括起來(lái)
2.頂點(diǎn)著色器與片段著色器的主函數(shù)名稱(chēng)可隨意,但需要再#pragma vert 與#pragma fragment中聲明并且與主函數(shù)名完全匹配,shader才會(huì)找到入口
3.float4是一種壓縮數(shù)組,float4 vert與float vert[4]嚴(yán)格意義上講不同,雖然都是存放4個(gè)float,但float4作為向量類(lèi)型做點(diǎn)乘、內(nèi)積等處理更快速
4.語(yǔ)義 :變量除了變量名與數(shù)據(jù)類(lèi)型之外,還在:后聲明其語(yǔ)義
例子一:RGB立方體
例題闡述:
給一個(gè)立方體(cube)創(chuàng)建一個(gè)shader,在立方體的直角坐標(biāo)系中,三個(gè)坐標(biāo)x,y,z的取值范圍為{0,0,0}至{1,1,1},而RGBA顏色red,green,blue,alpha的取值范圍正好是{0,0,0,0}至{1,1,1,1},將alpha寫(xiě)死為1,那么r,g,b分別與x,y,z建立一一映射,可得到一個(gè)6個(gè)面展示所有RGB顏色的立方體如圖:
具體代碼及其含義如下:
Shader "Custom/RGBCube" {
SubShader
{
Pass {
CGPROGRAM
#pragma vertex vert //頂點(diǎn)著色器入口函數(shù)聲明
#pragma fragment frag // 片段著色器入口函數(shù)聲明
//頂點(diǎn)輸出結(jié)構(gòu)體
struct vertexOutput {
//聲明結(jié)構(gòu)體的成員pos,類(lèi)型為float類(lèi)型的4元向量,語(yǔ)義為SV_POSITION,col同理;
float4 pos : SV_POSITION;
float4 col : TEXCOORD0;
};
//頂點(diǎn)著色器入口函數(shù)vert,與pragma第一條聲明匹配,返回類(lèi)型為剛剛定義的頂點(diǎn)輸出結(jié)構(gòu)體
vertexOutput vert(float4 vertexPos : POSITION)
{
vertexOutput output; //這里不需要struct關(guān)鍵字
//頂點(diǎn)著色器將數(shù)據(jù)寫(xiě)入輸出結(jié)構(gòu)體中。
output.pos = mul(UNITY_MATRIX_MVP, vertexPos);
//mul是頂點(diǎn)變換函數(shù),UNITY_MATRIX_MVP是unity的內(nèi)建矩陣,vertexPos是這個(gè)函數(shù)的形參
//此行代碼的作用為將形參vertexPos(本例即Cube對(duì)象的頂點(diǎn)向量)按照unity的內(nèi)建矩陣進(jìn)行頂點(diǎn)變換
output.col = vertexPos + float4(0.5, 0.5, 0.5, 0.0);
//這行代碼是實(shí)現(xiàn)RGB立方體的關(guān)鍵
//vertexPos的值域?yàn)轭}干所提到的x,y,z三元組各自減去0.5構(gòu)成的值域
//但是這里接受的類(lèi)型為float4,可見(jiàn)第四元應(yīng)該是無(wú)意義的常數(shù)1
//意思是vertexPos的值域?yàn)閧-0.5,-0.5,-0.5,1}至{0.5,0.5,0.5,1}
//而對(duì)這個(gè)值域進(jìn)行+{0.5,0.5,0.5,0}的矢量相加才能得到RGB (A恒定為1)的所有顏色區(qū)間
return output;
//將輸出結(jié)構(gòu)體返回,進(jìn)入下一個(gè)環(huán)節(jié)(簡(jiǎn)單理解為給片段著色器)
//ps:更細(xì)致的環(huán)節(jié)有頂點(diǎn)變換-->頂點(diǎn)著色-->幾何元的構(gòu)建-->光柵化幾何元
//-->片段著色-->略
}
//片段著色器入口函數(shù)frag,與pragma第二條聲明匹配,返回類(lèi)型為float4語(yǔ)義為COLOR,
//這里除了顏色沒(méi)有其他的輸出,所以沒(méi)有輸出結(jié)構(gòu)體
float4 frag(vertexOutput input) : COLOR
//此函數(shù)的形參類(lèi)型為頂點(diǎn)著色器的輸出結(jié)構(gòu)體,沒(méi)有語(yǔ)義
//原因就在于片段著色器位于頂點(diǎn)著色器的下一個(gè)環(huán)節(jié),參數(shù)按照這個(gè)順序傳遞
{
//由于col屬性已經(jīng)在頂點(diǎn)著色器中計(jì)算,直接返回進(jìn)入下一環(huán)節(jié)
//下一環(huán)節(jié)是什么這里不探討了
return input.col;
}
ENDCG
}
}
//如果以上SubShader渲染失敗則回滾采用Diffuse
FallBack "Diffuse"
}
補(bǔ)充:
剛剛寫(xiě)掉了,為何vertexPos的值域?yàn)閧-0,5,-0.5,-0.5,1}至{0.5,0.5,0.5,1}而非{0,0,0,1}至{1,1,1,1}呢?
因?yàn)槲覀兊闹苯亲鴺?biāo)系原點(diǎn)沒(méi)有在頂點(diǎn)上而是在cube的幾何中心,故其值域?yàn)閧-0,5,-0.5,-0.5,1}至{0.5,0.5,0.5,1},over