有一段時間沒寫文章了,這段時間一直在學(xué)習(xí)shader和工作,好了,不多說了,來記錄下自己的學(xué)習(xí)過程。
先從最簡單的例子看起:
Shader "Unity Sahders/TestOne"{
SubShader{
Pass{
CGPROGRAM
#progrma vertex vert
#progrma fragment frag
float4 vert(float4 v:POSITION):SV_POSITION{
return mul(UNITY_MARTIX_MVP,v);
}
fixed4 frag():SV_Target{
return fixed4(1.0,1.0,1.0,1.0);
}
ENGCG
}
}
}
這是一個很簡單的Shadr程序,那么問題來了,一開始肯定會有很多疑問:
第一行Shader "Unity Sahders/TestOne"通過Shader語義定義了這個Unity Shader的名字,你可以在選擇shader時通過Editor面板快速找到
第二行SubShader,一個unity文件可以包含多個SubShader語義塊,但最少要有一個。當(dāng)unity加載這個shader時,unity會掃描到所有的SubShader語義塊,然后選擇第一個能夠在目標平臺上運行的SubShader。如果都不支持的話,unity就會使用Fallback語義指定的SubShader。
第三行Pass,SubShader中定義了一系列Pass以及可選的狀態(tài)([RenderSetup])和標簽([Tags])設(shè)置。每個Pass定義了一次完整的渲染流程,但如果Pass的數(shù)目過多,往往會造成渲染性能的下降。因此我們應(yīng)當(dāng)盡量試用最小數(shù)目的Pass。狀態(tài)和標簽同樣可以在SubShader中聲明。不同的是,SubShader中的一些標簽是特定的,也就是說這些標簽設(shè)置和Pass中使用的標簽設(shè)置是不一樣的,而對于狀態(tài)設(shè)置來說,其使用的語法是相同的。但是如果我們在SubSahder中進行了這些設(shè)置,那么將會用于所有的Pass。
第四行CGPROGRAM,首先,unity使用的是Nvdia的CG語言但是和其還是有些不同(先不關(guān)注),準確的來說是CG/HLSL,當(dāng)然這里的CG/HLSL是unity經(jīng)過封裝后提供的,有些標準的CG/HLSL原生用法和函數(shù)unity并沒有提供(笑2333)。表面著色器、定點和片元著色器代碼就定義在CGPROGRAM和ENGCG之間。當(dāng)然需要注意的是表面著色器是直接寫在SubShader下的。
還有需要注意的是,如果沒有進行渲染設(shè)置和標簽設(shè)置,SubShader將使用默認的渲染設(shè)置和標簽設(shè)置
第五、第六行#progrma vertex vert和#progrma fragment frag,定義了頂點著色器的函數(shù)名為vert,片元著色器的函數(shù)名為frag,當(dāng)然,名字可以取其他的,這么寫比較直觀而且符合常規(guī)。
第七、第八行是關(guān)于vert的具體內(nèi)容,它是逐頂點執(zhí)行的。vert函數(shù)的輸入v包含了頂點的位置,這是通過POSITION語義指定的。它的返回值是一個float4的變量,它是該頂點在裁剪空間中的位置,POSITION和SV_POSITION都是CG/HLSL的語義,它們是不可忽略的,這些語義告訴系統(tǒng)用戶需要輸入哪些值,以及輸出是什么。例如這里,POSITION將告訴unity,把模型的頂點坐標填充到輸入?yún)?shù)v中,SV_POSITION將告訴unity,頂點著色器的輸出是裁減空間中的頂點坐標。如果沒有這些語義,渲染器就不知道該如果進行輸入輸出,return mul(UNITY_MARTIX_MVP,v);這一句就是把頂點坐標從模型空間轉(zhuǎn)換到裁剪空間。對于圖形學(xué)中的數(shù)學(xué)知識如果知道的話就很明白,這個單詞也很直白,MARTIX意為矩陣,MVP意為Mode、View、Projection,指模型變換、視圖變換、投影變換,關(guān)于這些數(shù)學(xué)知識可以查閱相關(guān)資料。
對于片元著色器的代碼,frag沒有輸入。它的輸出是一個fixed4的變量,并使用了SV_Target語義進行限定。SV_Target也是HLSL的系統(tǒng)語義,它意為告訴渲染器把用戶的輸出顏色存儲到一個渲染目標(render target)中,這里將輸出到默認的幀緩存中。結(jié)果是返回了一個表示白色的fixed4類型的變量,片元著色器輸出的顏色每個分量范圍在[0,1],其中[0,0,0]表示黑色,[1,1,1]表示白色。
額外補充的是SV_開頭的語義是System Value Semantics,即系統(tǒng)值語義,所以學(xué)好英文多方便理解==