1.最初的顶点/片元着色器
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
//定义Shader的名字
Shader"Unity Book/Chapter5/Simple Shader"{
//SubShader语句块
SubShader{
//Pass语句块
Pass{
//CG语句块
CGPROGRAM
//告诉Unity函数vert包含了顶点着色器的代码
#pragma vertex vert
//告诉Unity函数frag包含了片元着色器的代码
#pragma fragment frag
//顶点着色器函数,返回值是float4类型的变量,输入float4类型的参数v,
//POSITION告诉Unity把模型的定点坐标输入到v中
//SV_POSITION告诉Unity顶点着色器输出的是裁剪空间中的定点坐标
float4 vert(float4 v : POSITION) : SV_POSITION{
//把顶点坐标从模型空间转换到裁剪空间
return mul(UNITY_MATRIX_MVP,v);
}
//片元着色器函数,返回值是fixed4类型的变量,无输入参数
//SV_Target告诉渲染器把用户的输出颜色存储到一个渲染目标中
fixed4 frag() : SV_Target{
//返回一个表示白色的fixed4类型变量,(R,G,B,A)
return fixed4(1.0,1.0,1.0,1.0);
}
ENDCG
}
}
}
2.访问模型每个顶点的纹理坐标与法线方向
Shader"Unity Book/Chapter5/Simple Shader"{
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//使用一个结构体来定义顶点着色器的输入
//a2v:a表示应用(application),v表示顶点着色器(vertex shader)
//a2v表示把数据从应用阶段传递到顶点着色器中
struct a2v {
//POSITION语义告诉Unity,用模型空间的顶点坐标填充vertex变量
float4 vertex : POSITION;
//NORMAL语义告诉Unity,用模型空间的法线方向填充normal变量
float3 normal : NORMAL;
//TEXCOORD0语义告诉Unity,用模型的第一套纹理坐标填充texcoord变量
float4 texcoord : TEXCOORD0;
};
float4 vert(a2v v : POSITION) : SV_POSITION{
//使用v.vertex来访问模型的顶点坐标
return UnityObjectToClipPos (v.vertex);
}
fixed4 frag() : SV_Target{
return fixed4(1.0,1.0,1.0,1.0);
}
ENDCG
}
}
}
3.顶点着色器与片元着色器的通讯,即把模型的法线、纹理坐标等传递给片元着色器
Shader"Unity Book/Chapter5/Simple Shader"{
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
//使用一个结构体来定义顶点着色器的输出
struct v2f {
//SV_POSITION语义告诉Unity,pos里包含了顶点在裁剪空间中的位置信息
float4 pos : SV_POSITION;
//COLOR0语义可以用于存储颜色信息
fixed3 color : COLOR0;
};
v2f vert(a2v v) {
//声明输出结构
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
//v.normal包含了顶点的法线方向,其分量范围在[-1.0,1.0]
//下面的代码把分量范围映射到了[0.0,1.0]
//存储到o.color中传递给片元着色器
o.color = v.normal * 0.5 + fixed3(0.5, 0.5, 0.5);
return o;
}
fixed4 frag(v2f i) : SV_Target{
//将插值后的i.color显示到屏幕上
return fixed4(i.color,1.0);
}
ENDCG
}
}
}
4.在材质面板上显示属性
Shader"Unity Book/Chapter5/Simple Shader"{
//在材质面板上显示的属性写在这里
Properties{
//声明一个Color类型的属性,初始值是白色
_Color("Color Tint",Color) = (1.0,1.0,1.0,1.0)
}
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//在Cg代码中,我们需要定义一个与属性名称和类型都匹配的变量
//uniform是一种修饰词,可省略
uniform fixed4 _Color;
struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
fixed3 color : COLOR0;
};
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;
}
fixed4 frag(v2f i) : SV_Target{
return fixed4(i.color,1.0);
}
ENDCG
}
}
}
表 ShaderLab属性类型和Cg变量类型的匹配关系
ShaderLab属性类型 | Cg变量类型 |
Color , Vector | float4 , half4 , fixed4 |
Range , Float | float , half , fixed |
2D | sampler2D |
Cube | samplerCube |
3D | sampler3D |