概述
兰伯特光照模型认为漫反射光的强度仅与入射光的方向和反射点处表面法线的夹角的余弦成正比
漫反射光颜色 = 光源的颜色 * 材质的颜色 * max (0, 标准化后物体表面法线向量 * 标准化后光源方向向量)
ShaderLab示例
兰伯特光照模型逐顶点光照
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
// 材质漫反射颜色
fixed4 _MainColor;
// 顶点着色器传递给片元着色器的内容
struct v2f
{
// 裁剪空间下的顶点坐标信息
float4 pos: SV_POSITION;
// 对应顶点的漫反射光照颜色
fixed3 color: COLOR;
};
// 逐顶点光照 所以把光照计算写在顶点着色器中
v2f vert(appdata_base v)
{
v2f o;
// 模型空间下的顶点转换到世界坐标系
o.pos = UnityObjectToClipPos(v.vertex);
// 获取世界坐标下的法线信息
float3 normal = UnityObjectToWorldNormal(v.normal);
// 获取归一化的光源方向
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 color = _LightColor0.rgb * _MainColor * max(0, dot(normal, lightDir));
// 记录颜色 传递给片元着色器
o.color = color + UNITY_LIGHTMODEL_AMBIENT.rgb;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// 把计算好的兰伯特光照颜色传递出去
return fixed4(i.color.rgb, 1);
}
ENDCG
}
兰伯特光照模型逐片元光照
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _MainColor;
struct v2f
{
// 裁剪空间下的顶点位置
float4 vertex : SV_POSITION;
// 世界空间下的法线位置
float3 normal : NORMAL;
};
v2f vert(appdata_base v)
{
v2f o;
// 转换模型空间下的顶点到裁剪空间中
o.vertex = UnityObjectToClipPos(v.vertex);
// 转换模型空间下的法线到世界空间中
o.normal = UnityObjectToWorldNormal(v.normal);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// 得到光源单位向量
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 color = _LightColor0.rgb * _MainColor.rgb * max(0, dot(i.normal, lightDir));
color = UNITY_LIGHTMODEL_AMBIENT + color;
return fixed4(color.rgb, 1);
}
ENDCG
}