Lambert (兰伯特)光照模型
是光源照射到物体表面后,向四面八方反射,产生的漫反射效果。这是一种理想的漫反射光照模型。如下图:这个是顶点函数处理后的该光照模型,因此看起来像素不够平滑。
漫反射
是投射在粗糙表面上的光向各个方向反射的现象。当一束平行的入射光线射到粗糙的表面时,表面会把光线向着四面八方反射,所以入射线虽然互相平行,由于各点的法线方向不一致,造成反射光线向不同的方向无规则地反射,这种反射称之为“漫反射”或“漫射”。这种反射的光称为漫射光。
Lambert光照模型计算方法
漫反射光的强度近似地服从于Lambert定律,即漫反射光的光强仅与入射光的方向和反射点处表面法向夹角的余弦成正比。
原理公式:diffuse = I*cosθ;
diffuse:反射光线的的光强;
I:入射光线的光强,方向如上图所示;
cosθ:入射光线和该顶点法线的余弦,如上图所示;cosθ = L*N;
所以,最后的数学表达式为:diffuse = I*(L*N);
Shader程序
/*******************************************
Lambert(兰伯特)光照模型
1. 理想的漫反射;
2. 计算都在顶点着色器,因此像素不会平滑过渡;
*******************************************/
Shader "JQM/Lambert"
{
Properties
{
_Color("Color", color) = (1.0,1.0,1.0,1.0)
}
SubShader{
Pass{ Tags { "LightMode" = "ForwardBase"} CGPROGRAM
#pragma vertex vert
#pragma fragment frag //使用自定义变量
uniform float4 _Color; //使用Unity定义的变量
uniform float4 _LightColor0; struct vertexInput{
float4 vertex:POSITION;
float3 normal:NORMAL;
}; struct vertexOutput{
float4 pos:SV_POSITION;
float4 col:COLOR;
}; //顶点程序
vertexOutput vert(vertexInput v)
{
vertexOutput o; float3 normalDirection = normalize( mul(float4(v.normal,0.0),_World2Object).xyz);//将模型空间的法线转到世界空间
float3 lightDirection;
float atten = 1.0; lightDirection = normalize(_WorldSpaceLightPos0.xyz);//灯光方向
float3 diffuseReflection = atten * _LightColor0.xyz * max(0.0, dot(normalDirection,lightDirection));//计算兰伯特漫反射
float3 lightFinal = diffuseReflection + UNITY_LIGHTMODEL_AMBIENT.xyz;//与环境光结合 o.col = float4(lightFinal*_Color.rgb,1.0);
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
} //片段程序
float4 frag(vertexOutput i):COLOR
{
return i.col;
} ENDCG
}
} }
效果图
物体在空间中 受到 光源 环境光 和 自身材质(颜色,贴图) 的综合因素的影响,形成的效果。