摘自冯乐乐的《unity shader 入门精要》
首先给shader其一个名字
Shader "Custom/DiffuseVertxLevelMat"
#include "Lighting.cginc"
Properties
{
_Diffuse("Diffuse",Color)=(1,1,1,1)
}
SubShader
{
Pass
{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
fixed4 _Diffuse;
struct a2v
{
float4 vertex:POSITION;
float4 normal:NORMAL;
};
struct v2f
{
float4 pos:SV_POSITION;
fixed3 color:COLOR;
};
v2f vert(a2v v)
{
v2f o;
//Transform the vertex from object space to projection space
//变换对象空间的顶点投影空间
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
//get ambient term
//获得环境光照
fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;
//transform the normal from object space world space
//把局部法线转换到世界法线
fixed3 worldNormal=normalize(mul(v.normal,(float3x3)_World2Object));
//get the light direction in world space
//获得全局光照
fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz);
//compute diffuse term
//计算漫反射
fixed3 diffuse =_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLight));
o.color=ambient+diffuse;
return o;
}
fixed4 frag(v2f i):SV_Target
{
return fixed4(i.color,1.0);
}
ENDCG
}
}
Shader "Custom/DiffuseVertexLevel" {
Properties
{
_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)
}
SubShader
{
Pass // 顶点/片元着色器的代码需要写在Pass语义块中
{
//光照模型
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
//顶点着色器 的名称
#pragma vertex vert
//片元着色器 的名称
#pragma fragment frag
//使用Unity内置的一些变量,如后面的_LightColor0,所以需要
//包含 Lighting.cginc
#include "Lighting.cginc"
//定义一个Properties语义块中声明的属性一样类型匹配的变量
//通过这种方式,我们可以得到漫反射公式中需要的参数,材质漫反射属性,
//由于颜色属性的范围在0到1之间,因此我们使用fixed精度变量来存储它
fixed4 _Diffuse;
//顶点着色器的输入结构体
struct a2v
{
float4 vertex : POSITION;
//用于访问顶点法线,通过NORMAL语义来告诉Unity把模型顶点法线信息存储到normal变量中
float3 normal : NORMAL;
};
//顶点着色器的输出结构体(同事也说片元着色器的输入结构体)
struct v2f
{
float4 pos : SV_POSITION;
//为了接受顶点着色器计算得到的光照颜色并作用于片元着色器,
//我们定义了一个color变量,且并不是必须使用COLOR语义,
//有的是使用TEXCROOD0语义
fixed3 color : COLOR;
};
//顶点着色器最基本的任务就是把顶点位置从模型空间转换到裁剪空间中
// 所以使用unity内置的 UNITY_MATRIX_MVP 完成 模型*世界*投影矩阵来完成转换
v2f vert(a2v v)
{
v2f o;
//Transform the vertex from object space to projection space
//变换对象空间的顶点投影空间
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
//get ambient term
//获得环境光照
//获取环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
//transform the normal from object space world space
//把局部法线转换到世界法线
fixed3 worldNormal = normalize(mul(v.normal, (float3x3)_World2Object));
// _WorldSpaceLightPos0 获取光源方向
//get the light direction in world space
//获得全局光照
fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
//compute diffuse term
//计算漫反射
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLight));
o.color = ambient + diffuse;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
return fixed4(i.color, 1.0);
}
ENDCG
}
}
FallBack "Diffuse"
}
然后就是效果显示的对照图: