實(shí)現(xiàn)一個(gè)簡(jiǎn)單地Shader
Shader "Unlit/SimpleShader"
{
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 vert(float4 v : POSITION) :SV_POSITION{
return mul(UNITY_MATRIX_MVP,v);
}
float4 frag() : SV_TARGET{
return fixed4(1.0,1.0,0.5f,1.0);
}
ENDCG
}
}
}
在CGPROGRAM到CGEND中間添加代碼片段的編譯指令和Cg代碼.
#pragma vertex vert
#pragma fragment frag
告訴編譯器那個(gè)函數(shù)執(zhí)行頂點(diǎn)著色器,那個(gè)函數(shù)執(zhí)行片元著色器.
float4 vert(float4 v : POSITION) :SV_POSITION{
return mul(UNITY_MATRIX_MVP,v);
}
使用頂點(diǎn)著色器代碼,它是逐頂點(diǎn)進(jìn)行,輸入的參數(shù)包含了頂點(diǎn)位置,通過POSITION語(yǔ)義指定.
返回一個(gè)float4,它是該頂點(diǎn)在裁剪空間中的位置,通過SV_POSITION定義,UNITY_MATRIX_MVP是Unity內(nèi)置的模型-觀察-投影矩陣.
float4 frag() : SV_Target{
return fixed4(1.0,1.0,0.5f,1.0);
}
frag沒有任何輸入,輸出一個(gè)float4,用SV_Target定義,等同于告訴渲染器,用戶輸出的顏色存儲(chǔ)到一個(gè)渲染目標(biāo).
當(dāng)我們需要更多的模型數(shù)據(jù)的時(shí)候,我們將為頂點(diǎn)著色器定義一個(gè)新的參數(shù),這個(gè)參數(shù)將是一個(gè)結(jié)構(gòu)體,結(jié)構(gòu)體中包含了法線 切線 紋理坐標(biāo)等諸多數(shù)據(jù)
struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
這里的a2v表示a(application) v(vertex shader),表示數(shù)據(jù)從應(yīng)用階段傳遞到頂點(diǎn)著色器中
POSITION等語(yǔ)義中的數(shù)據(jù)從MeshRender中傳遞過來(lái),每幀調(diào)用DrawCall的時(shí)候,MeshRender將他負(fù)責(zé)渲染的數(shù)據(jù)傳遞給UnityShader.
在給頂點(diǎn)著色器傳參數(shù)的時(shí)候傳a2v結(jié)構(gòu)體
我們聲明一個(gè)結(jié)構(gòu)體v2f,用于在頂點(diǎn)著色器和片元著色器之間進(jìn)行傳遞數(shù)據(jù)抢埋,
struct v2f {
float4 pos : SV_POSITION;
fixed3 color : COLOR0;//COLOR0語(yǔ)義用于存儲(chǔ)顏色信息
};
在頂點(diǎn)著色器中我們返回v2f的結(jié)構(gòu)體垄分,此結(jié)構(gòu)體中包含了SV_POSITION氛悬,在頂點(diǎn)著色器中,我們給color值蜈抓,來(lái)進(jìn)行逐頂點(diǎn)的color插值荆烈,數(shù)值選用法線的相關(guān)值。
v2f vert(a2v v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.color = v.normal*0.5 + fixed3(0.5,0.5,0.5);
return o;
}
在fragment中我們只用返回插值后的color
fixed4 frag(v2f i) : SV_Target{
return fixed4(i.color,1.0);
}
最終效果: