顶点程序计算光照执行效率高,片段程序计算光照较慢,但是效果更加细腻平滑。
从顶点集中传参数到片段集中,是不可以用NORMAL语义的
将光照计算从顶点程序集中移植到片段程序集中 :
struct v2f {
float4 pos : POSITION;
float3 normal : TEXCOORD1; // 不能使用NORMAL语义
float4 vertex : COLOR; // 只用来记录原始的顶点的位置信息
}
v2f vert(appdata_base v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP , v.vertex);
o.normal = v.normal; // 在顶点函数中,不作任何处理,只做赋值操作,变换操作,都放到片段程序中来做
o.vertex = v.vertex;
return o;
}
fixed4 frag(v2f IN) : COLOR {
// Ambient Color
fixed4 col = UNITY_LIGHTMODEL_AMBIENT ;
// Diffuse Color
// 对法线变换坐标系的操作,切忌放在顶点函数中,顶点函数只作赋值,变换操作要放在片段函数中
float3 N = UnityObjectToWorldNormal( IN.normal );
float3 L = normalize(WorldSpaceLightDir (IN.vertex));
float diffuseScale = saturate(dot(N,L));
col += _LightColor0 * _MainColor * diffuseScale ; // _MainColor 是物体本身的颜色,可以通过属性修改
// Specular Color
float3 V = normalize(WorldSpaceViewDir(IN.vertex));
float3 R = 2 * dot(N , L) * N - L ;
float specularScale = staurate(dot(R, V));
col += _SpecularColor * pow(specularScale , _Shininess);
// compute 4 points Lighting
float3 wpos = mul(_Object2World , IN.vertex) . xyz ;
col += Shade4PointLights(
unity_4LightPosX0 , unity_4LightPosY0 , unity_4LightPosZ0 ,
unity_LightColor[0].rgb , unity_LightColor[1].rgb ,
unity_LightColor[2].rgb , unity_LightColor[3].rgb ,
unity_4LightAtten0,
wpos , N ) ;
return col ;
}