对于光照模型,从算法理论基础而言,可分为两类,一类是基于物理理论的光照模型,另一种是基于经验的模型。从使用角度而言,可分为全局光照模型和局部光照模型,本文简单地介绍了几种最基础的经典局部光照模型.
1、 局部光照模型之Lambert
Lambert光照模型是一个非常简单的模型,早在200多年前,一个叫Lambert的家伙提出,当光照射到粗糙的表面时,它将向四周均匀的反射。这种各向同性的反射叫漫反射(Diffuse reflection)
漫反射光的强度服从于Lambert定律,漫反射的光强与入射光的方向和反射点处表面法向夹角的余弦成正比。Lambert模型的数学表达示如下:
Idiffuse = Kd*Id*cosθ
Kd表示物体表面漫反射属性,Id表时入射光强。若N表示入射点单位法向量,L表示从入射点指向光源的单位向量(注意是入射点指向光源,表示了入射光的方向),由点乘与cos之间的关系,cosθ = N●L,则Lmbert模型可表示为:
Idiffuse = Kd*Id*(N●L)
对应的PS如下:
float4 main( float4 Diff : COLOR0,
float3 Normal : TEXCOORD0,
float3 View : TEXCOORD1,
float3 Light : TEXCOORD2,
float2 Tex : TEXCOORD4 ) : COLOR
{
// Compute ambient term:
float4 AmbientColor = ambient * Ka;
// Compute diffuse term:
float4 DiffuseColor = diffuse * Kd * max( 0, dot( Normal, Light ));
float4 FinalColor = (AmbientColor + DiffuseColor) * tex2D( baseMap, Tex);
return FinalColor;
}
2、 局部光照模型之Phong
Lambert模型能很好的表示粗糙表面的光照,但不能表现出镜面反射高光。1975年Phong Bui Tong发明的Phong模型,提出了计算镜面高光的经验模型,镜面反射光强与反射光线和视线的夹角a相关:
Ispecular = Ks*Is*(cos a) n
其中Ks为物体表面的高光系数,Is为光强,a是反射光与视线的夹角,n为高光指数,n越大,则表面越光滑,反射光越集中,高光范围越小。如果V表示顶点到视点的单位向量,R表示反射光反向,则cos a可表示为V和R的点积。模型可表示为:
Ispecular = Ks*Is*(V●R) n
反射光放向R可由入射光放向L(顶点指向光源)和物体法向量N求出。
R = (2N●L)N – L
对应的PS如下:
float4 main( float4 Diff : COLOR0,
float3 Normal : TEXCOORD0,
float3 View : TEXCOORD1,
float3 Light : TEXCOORD2,
float2 Tex : TEXCOORD4 ) : COLOR
{
// Compute the reflection vector:
float3 vReflect = normalize( 2 * dot( Normal, Light) * Normal - Light );
// Compute ambient term:
float4 AmbientColor = ambient * Ka;
// Compute diffuse term:
float4 DiffuseColor = diffuse * Kd * max( 0, dot( Normal, Light ));
// Compute specular term:
float4 SpecularColor = specular * Ks * pow( max( 0, dot(vReflect, View)), n_specular );
float4 FinalColor = (AmbientColor + DiffuseColor) * tex2D( baseMap, Tex) + SpecularColor;
return FinalColor;
}
3、 局部光照模型之Blinn-Phong
图形学界大牛Jim Blinn对Phong模型进行了改进,提出了Blinn-Phong模型。Blinn-Phong模型与Phong模型的区别是,把V●R换成了N ●H,其中H为半角向量,位于法线N和光线L的角平分线方向。Blinn-Phong模型可表示为:
Ispecular = Ks*Is*(N●H) n
其中H = (L + V) / | L+V |,计算H比计算反射向量R更快速。
对应的PS如下:
float4 main( float4 Diff : COLOR0,
float3 Normal : TEXCOORD0,
float3 View : TEXCOORD1,
float3 Light : TEXCOORD2,
float2 Tex : TEXCOORD4 ) : COLOR
{
// Compute the reflection vector:
float3 H = normalize(View+Light);
// Compute ambient term:
float4 AmbientColor = ambient * Ka;
// Compute diffuse term:
float4 DiffuseColor = diffuse * Kd * max( 0, dot( Normal, Light ));
// Compute specular term:
float4 SpecularColor = specular * Ks * pow( max( 0, dot(H, Normal)), n_specular );
float4 FinalColor = (AmbientColor + DiffuseColor) * tex2D( baseMap, Tex) + SpecularColor;
return FinalColor;
}
4、 效果图
从左到右,依次是Lambert、Phong、Blinn-Phong,可以看出Phong和Blinn-Phong都有高光,但两者还是有些区别的。
5、其他光照模型
Torrance-Sparrow model
Cook-Torrance model
Ward's anisotropic model
Oren–Nayar model
Ashikhmin-Shirley model
HTSG
Fitted Lafortune model