基本數據類型與surface一致,就不在此文章贅述了
頂點語義綁定
float4 POSITION 頂點座標位置
float3 NORMAL 頂點法線向量座標
float4 TEXCOORD0 第一個UV座標
float4 TEXCOORD1..N 第二個到第N個UV座標
float4 TENGENT 頂點切線向量座標
float4 COLOR 頂點顏色值
常用函數庫
HLSLSupport.cginc 輔助爲跨平臺的着色器編譯宏和定義
UnityShaderVariables.cginc 常⽤用全局變量量
UnityCG.cginc 常⽤用輔助函數
AutoLight.cginc 光、影函數
Lighting.cginc 光照模型相關
TerrainEngine.cginc 地形植被輔助
首先我們應該知道頂點片段着色器的基本框架
Shader "MyVFShader/VFShader_001"
{
Properties
{
}
SubShader
{
Pass
{
CGPROGRAM
//預編譯指令關鍵詞 | 函數類型 | 函數名
#pragma vertex vert //vertex 是頂點着色器
#pragma fragment frag // fragment 是片段着色器
void vert(){}
void frag(){}
ENDCG
}
}
}
接下來先來用頂點片段着色器寫一個純色的Shader
Shader "MyVFShader/VFShader_002"
{
Properties
{
_MainColor("顏色",Color) = (1,1,1,1)
}
SubShader
{
Pass
{
CGPROGRAM
//預編譯指令關鍵詞 | 函數類型 | 函數名
#pragma vertex vert //vertex 是頂點着色器
#pragma fragment frag // fragment 是片段着色器
//輸入一個頂點座標 名稱vertexPos 語義綁定POSITION
//輸出一個像素座標 語義綁定SV_POSITION
float4 vert(float4 vertexPos:POSITION):SV_POSITION
{
//老版本寫法(Model View Project矩陣變幻,得到每個像素的座標位置)
return UnityObjectToClipPos(vertexPos);
//新版本寫法UnityObjectToClipPos(頂點座標)
return UnityObjectToClipPos(vertexPos);
}
float4 _MainColor;
//無輸入 輸出內插值顏色
float4 frag():COLOR
{
return _MainColor;
}
ENDCG
}
}
}
/*
我們來說一下步驟和思路 做一個總結
首先看頂點函數
1.參數 --> 每個頂點的座標位置 語義綁定是POSITION 類型是float4
2.返回值 --> 每個頂點的像素位置 語義綁定是SV_POSITION 類型是float4
3.頂點函數的作用:就是將三維空間座標投影到二維窗口
然後看片段函數
1.參數 --> 片段函數沒有參數
2.返回值 --> 片段的顏色值 語義綁定COLOR 類型是float4
3.片段函數的作用:就是給片段顏色賦值,也就是設置片段顏色
*/
如果感覺純色的太侷限了 我們來寫一下彩色的看看效果
Shader "MyVFShader/VFShader_003"
{
Properties
{
//_ColorOffset("顏色偏移量",Range(0,1)) = 0.5
_ROffset("紅色偏移量",Range(0,1)) = 0
_GOffset("綠色偏移量",Range(0,1)) = 0
_BOffset("藍色偏移量",Range(0,1)) = 0
}
SubShader
{
Pass
{
CGPROGRAM
//預編譯指令關鍵詞 | 函數類型 | 函數名
#pragma vertex vert //vertex 是頂點着色器
#pragma fragment frag // fragment 是片段着色器
//頂點輸出的結構體
struct V2F
{
//像素座標
float4 position:POSITION;
//0級紋理座標(可以理解爲像素的顏色)
float4 color:TEXCOORD0;
};
float _ROffset;
float _GOffset;
float _BOffset;
//頂點函數
//輸入一個頂點座標 名稱vertexPos 語義綁定POSITION
V2F vert(float4 vertexPos:POSITION)
{
//聲明結構體
V2F v2f;
//通過頂點座標求像素座標
v2f.position = UnityObjectToClipPos(vertexPos);
//頂點座標當做顏色值設置成像素顏色
//通過紅,綠,藍三個顏色的偏移量來修改顏色的變化
v2f.color = vertexPos + float4(_ROffset,_GOffset,_BOffset,0);
//返回
return v2f;
}
//片段函數
float4 frag(V2F v2f):COLOR
{
return v2f.color;
}
ENDCG
}
}
}
/*
我們來說一下步驟和思路 做一個總結
頂點着⾊色器器輸出結構體
1.float4 postion:SV_POSITION 空間位置
2.float4 color:TEXCOORD0 0級紋理理座標
首先看頂點函數
1.參數 --> 每個頂點的座標位置 語義綁定是POSITION 類型是float4
2.返回值 --> 輸出結構體
3.頂點函數的作用:將三維空間座標投影到⼆維口,顏⾊值設置爲頂點座標+偏移量(營造彩虹效果)
然後看片段函數
1.參數 --> 頂點着⾊器輸出結構體
2.返回值 --> 片段的顏色值 語義綁定COLOR 類型是float4
3.片段函數的作用:直接將頂點輸出的顏色設置到片段顯示
*/
由淺至深的 接下來 我們看一下頂點片段着色器的漫反射應該怎樣實現
Shader "MyVFShader/VFShader_004"
{
Properties
{
_Color("顏色",Color) = (1,0,0,1)
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex ver
#pragma fragment frag
//引用庫
#include "UnityCG.cginc"
//聲明外部顏色變量
float4 _Color;
//聲明內部光照顏色變量
float4 _LightColor0;
//頂點函數輸入結構體
struct appData
{
//頂點座標
float4 vertexPos:POSITION;
//頂點法線
float3 normal:NORMAL;
};
struct V2F
{
//像素座標
float4 position:SV_POSITION;
//像素法線
float3 normal:NORMAL;
};
//頂點函數
V2F ver(appData data)
{
//定義輸出結構體
V2F v2f;
//座標系轉換
v2f.position = UnityObjectToClipPos(data.vertexPos);
//從頂點法線 到 像素法線
v2f.normal = mul(float4(data.normal,0),unity_WorldToObject).xyz;
//返回
return v2f;
}
//片段函數
float4 frag(V2F v2f):COLOR
{
//求法線的單位向量
float3 v2fnormal = normalize(v2f.normal);
//求入射光的單位向量 _WorldSpaceLightPos0內部函數
float3 lnormal = normalize(_WorldSpaceLightPos0.xyz);
//逆向光公式:Diffuse=LightColor * MainColor * max(0,dot(N,L))
//正向光公式:Diffuse=LightColor * MainColor * -min(0,dot(N,L))
float3 diffuse = _LightColor0 * _Color * -min(0,dot(v2fnormal,lnormal));
//添加環境光
float4 newDiffuse = float4(diffuse,0) + UNITY_LIGHTMODEL_AMBIENT;
//返回顏色值
return newDiffuse;
}
ENDCG
}
}
FallBack "Diffuse"
}
/*
我們來說一下步驟和思路 做一個總結
第一步
1.引入庫 #include “UnityCG.cginc”
頂點着色器輸入結構體
1.頂點位置 語義綁定POSITION 類型float4
2.法線 語義綁定NORMAL 類型float3
頂點着⾊器輸出結構體
1.像素位置 語義綁定SV_POSITION 類型float4
2.法線 語義綁定NORMAL 類型float3
全局變量聲明
1.光照顏色 內部值 _LightColor0 類型float4
2.漫反射顏色 屬性值 自己定義
首先看頂點函數
1.參數 --> 輸入結構體
2.返回值 --> 輸出結構體
3.步驟:
1.矩陣變幻
2.計算法線
1).輸入法線擴充 : float4(input.normal, 0.0)
2).內部值 : unity_WorldToObject
3).法線計算 : mul(float4(input.normal, 0.0), unity_WorldToObject).xyz
然後看片段函數
1.參數 --> 頂點着⾊器輸出結構體
2.返回值 --> 片段的顏色值 語義綁定COLOR 類型是float4
3.步驟:
1.獲取輸入法線方向(float3) normalize(input.normal)
2.獲取入射光法線方向(float3)normalize(_WorldSpaceLightPos0.xyz)
3.計算漫反射值
1).逆向光公式:Diffuse=LightColor * MainColor * max(0,dot(N,L))
2).正向光公式:Diffuse=LightColor * MainColor * -min(0,dot(N,L))
i).LightColor 光照顏⾊色
ii).MainColor 漫反射顏⾊色
iii).N 輸⼊入法線
iiii).L 光照法線
4.合併環境光
1).漫反射擴充 float4(diffuse, 1.0)
2).添加環境光 + UNITY_LIGHTMODEL_AMBIENT
5.返回結果 片段顏色
*/
Shader就先介紹這麼多了,感謝大家的支持, 如果有人想要深入的研究,可以給我評論留言,我們一起討論研究!!!!