1. 程式人生 > >unityShader之頂點著色器和片段著色器(一)

unityShader之頂點著色器和片段著色器(一)

頂點著色器和片段著色器作為效能不錯,實現效果也很好的渲染方式,這裡分幾個小結著重說一說,然後所有關鍵字的使用以及特殊語義的含義都在程式碼裡註釋了,有不明白的可以討論下:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
shader"likang/king05" { properties { _MainTex("baseTexture",2d) = "white"{} } //頂點著色器和片段著色器 subshader { pass { CGPROGRAM //必須大寫,不然會報錯 //cgprogram #pragma vertex vert //vertex 不能大寫 頂點著色器函式vert #pragma fragment frag //fragment 不能大寫 片段著色器函式frag #include "unitycg.cginc"
//引用庫,包含很多輔助函式 sampler2D _MainTex; //紋理 //不宣告_MainTex_ST 這個變數,下面的49行會報錯,解釋看52行 float4 _MainTex_ST; //紋理的縮放和偏移 就是Tiling/Offset 值(Tiling.x,Tiling.y,Offset.x,Offset.y) struct v2f { //SV_POSITION 輸出的資料結構包含了最終轉換過的,將用於光柵化的頂點座標 //POSITION 轉換之前的模型頂點座標(自身座標軸)
//模型頂點座標要經過一系列的矩陣變換,最終變成螢幕上的畫素座標 float4 pos:SV_POSITION; float2 uv:TEXCOORD0; //第一張貼圖的uv座標 TEXCOORD1 第二張貼圖的uv座標 }; //unity內建的常用資料結構 //appdata_base 其含義就是輸入到頂點著色器的資料(包含position,normal,one texture coordinate) //appdata_tan 輸入到頂點著色器的資料(包含position,normal,tangent,one texture coordinate) //appdata_full 輸入到頂點著色器的資料(包含position,normal,tangent,vertex color,two texture coordinates) //appdata_img 輸入到頂點著色器的資料(包含position,one texture coordinate) v2f vert(appdata_base v) { v2f o; // o.pos = UnityObjectToClipPos(v.vertex);等同於o.pos = mul(UNITY_MATRIX_MVP,v.vertex); //後者效能上優於前者,unity推薦使用後者 //UNITY_MATRIX_MVP為unity內建的矩陣。該矩陣乘以頂點在模型座標系下的座標得到投影座標 //類似的矩陣還有 UNITY_MATRIX_MV 模型座標系(以模型某點為原點)-->觀察者座標系(以相機為原點) //UNITY_MATRIX_VP 觀察者座標系-->投影座標系 //UNITY_MATRIX_T_MV 轉置模型-->觀察者座標系 //UNITY_MATRIX_TEXTURE0 to UNITY_MATRIX_TEXTURE3 紋理變換矩陣 等等…… //mul(M,v) 矩陣與向量相乘 得到新的向量(模型座標在投影座標系下的新座標) o.pos = mul(UNITY_MATRIX_MVP,v.vertex); //TRANSFORM_TEX 函式的含義就是將頂點的uv座標和Tiling和Offset做運算 //因此你在shader屬性中變化Tiling和Offset的值,紋理會發生改變 o.uv = TRANSFORM_TEX(v.texcoord,_MainTex); //上面的等式等同於o.uv = v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw; //所以上面要宣告_MainTex_ST變數,不然這裡會報錯 //如果採用預設的Tiling(1,1),Offset(0,0),那麼在shader面板改變Tiling和Offset的值就沒什麼用了 // o.uv = v.texcoord.xy; return o; } //將經過頂點著色器處理過的資料拿給片段著色器接著處理(給每個畫素著色) float4 frag(v2f i):COLOR { //tex2D函式 CG內建函式:用來取樣2d紋理 float4 texCol = tex2D(_MainTex,i.uv); return texCol; } ENDCG //endcg } } fallback"diffuse" }

這裡寫圖片描述