UnityShader的基本结构。它包含了Shader、Properties、SubShader、Fallback等语义块。顶点/片元着色器结构与之大体类似,它的结构如下:
Shader "MyShaderName"{
Properties{
//属性
}
SubShader
{
//针对显卡A的SubShader
Pass{
//设置渲染状态和标签
//开始CG代码片段
CGPROGRAM
//该代码片段的编译指令,比如:
#pragma vertex vert //顶点着色器函数声明,此名字为任意合法函数名
#pragma fragment frag //片元着色器函数声明,此名字为任意合法函数名
//CG代码写在这里
ENDCG
//其他设置
}
//其他需要的Pass
}
SubShader{
//针对显卡B的SubShader
}
//上述SubShader都失败后用于回调的UnityShader
FallBack "VertexLit"
}
其中最重要的部分是Pass语义块,我们绝大部分的代码都是卸载这个语义块里面的。
第一个UnityShader
Shader "Custom/TestShader"
{
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//使用一个结构体来定义顶点着色器的输入
struct a2v{
//POSITION 语义告诉Unity,用模型空间的顶点坐标填充vertex变量
float4 vertex : POSITION;
//NORMAL 语义告诉Unity,用模型空间的法线方向填充normal变量
float3 normal : NORMAL;
//TEXCOORD0 语义告诉Unity,用模型的第一套纹理坐标填充texcoord变量
float4 texcoord : TEXCOORD0;
};//此处结构体结尾一定要记着加;
//使用一个结构体来定义片元着色器的输出
struct v2f{
//SV_POSITION 语义告诉Unity,pos里包含了顶点在裁剪空间中的位置信息
float4 pos : SV_POSITION;
//COLOR0 语义可以用于存储颜色信息
fixed3 color : COLOR0;
}
v2f vert(){
//声明输出结构
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,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
}
}
}
使用效果如下