但是我们会发现物体的背光面是个全黑的颜色,现实生活中物体的背光面并不是全黑的,而是可以看到物体的大概形状,并不是全黑的,之前使用的计算方式是兰伯特光照模型。要实现此种现象,那么就需要使用半兰伯特光照模型来实现
半兰伯特光照模型
Diffuse = 直射光颜色 *(cosθ*0.5+0.5)
兰伯特光照模型
Diffuse = 直射光颜色 * max(0,cosθ) θ是指光照方向与法线方向的夹角
半兰伯特光效果如图:
高光反射的计算 (Blinn光照模型)
Specular = 直射光*pow(max(cosθ,0),高光的参数)
对于上述公式的解释:
θ是指反射光方向和反射点到相机方向的夹角
pow的次方的意思 就是cosθ的高光参数次方
max(cosθ,0)作用是防止在物体背光面,如果高光参数为偶数,那么最后的值会从负数变为正数
使用的示例代码如下
Properties{
_Diffuse("Diffuse Color",Color) = (1,1,1,1)
_Gloss("Gloss",Range(8,200)) = 10
}
SubShader{
Pass{
Tags{
"LightMode" = "ForwardBase"}
CGPROGRAM
#include "Lighting.cginc"
//unity系统定义好的类 可以使用一些内置的变量来简化计算操作
//_LightColor0 该变量表示第一个直射光的颜色
//_WorldSpaceLightPos0 该变量表示第一个直射光的位置(世界坐标下)
//UNITY_LIGHTMODEL_AMBIENT 该变量表示系统的环境光
#pragma vertex vert
#pragma fragment frag
fixed4 _Diffuse;
half _Gloss;
struct a2v {
float4 vertex : POSITION; //系统自动将顶点坐标传入vertex
float3 normal : NORMAL; //系统自动将法线传入 变量normal
};
struct v2f {
float4 position:SV_POSITION;
fixed3 color : COLOR;
};
v2f vert(a2v x) {
v2f f;
//UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间
f.position = mul(UNITY_MATRIX_MVP, x.vertex);