Lambert漫反射光照模型归纳

此模型属于经验模型,主要用来简单模拟粗糙物体表面的光照现象

 

此模型假设物体表面为理想漫反射体(也就是只产生漫反射现象,也成为Lambert反射体),同时,场景中存在两种光,一种为环境光,一种为方向光,然后我们分别计算这两种光照射到粗糙物体表面所产生的光照现象,最后再将两个结果相加,得出反射后的光强值。

 

首先是计算环境光的公式:

I_ambdiff = K_d * I_a;

其中,K_d为粗糙物体表面材质对光的反射系数,这个系数由程序编写者在宿主程序中给出,I_a为环境光的光强,也就是环境光的颜色数值,一般是一个float3型的变量。

 

然后是计算方向光的公式:

I_ldiff = K_d * I_l * cosa;

其中I_l为方向光的光强,也就是其颜色值,一般是float3型的变量。这个公式与计算环境光的不同,对于环境光,我们不关心它的方向,因为环境光也没有方向,它给予物体的光照在各个顶点处均是一样的。而方向光则需要关注其方向,例如一个聚光灯,灯从不同的角度来照射物体所产生的效果也是不一样的,光线方向越靠近法线,漫反射出来的光就越强,反之则越弱。公式中的a就是光线方向与顶点法线的夹角,同时要注意,入射光的方向在这里定义为顶点到光源位置。但是计算cosa会比较麻烦,所以在这里要变换一下公式,方便程序的书写。假设N为顶点的单位法向量,L为入射光的单位法向量(再次提醒一下,L的方向是由顶点指向光源的)这样,由向量的点积公式可得:cosa = N﹒L,所以计算方向光的公式就变为:

I_ldiff = K_d * I_l * (N﹒L);

 

综上,得出漫反射后的光强为:

I_diff = K_d * I_a + K_d * I_l * (N﹒L);

 

 

下面给出使用Cg语言的Lambert漫反射光照模型顶点着色程序:

/******************************************************/

/*Lambert漫反射光照模型                                */

/******************************************************/

 

struct vertex_In

{

   float4 in_Position : POSITION;

   float4 in_Normal   : NORMAL;

};

 

struct vertex_Out

{

   float4 out_Position : POSITION;

   float4 out_Color    : COLOR0;

};

 

void main_v(vertex_In vertexI,

                    out vertex_Out vertexO,

 

                    uniform float4*4 modelViewProj,

                    uniform float4*4 worldMatrix,

                    uniform float4*4 worldMatrix_IT,

                    uniform float3 globalAmbient,//全局光光强

                    uniform float3 lightPosition,

                    uniform float3 lightColor,

                    uniform float3 K_d//漫反射体反射系数

                    )

{

    vertexO.out_Position = mul(modelViewProj , vertexI.in_Position);//进行投影变换

 

    float3 worldPosition = mul(worldMatrix , vertexI.in_Position).xyz;//计算顶点的世界位置

 

    float3 N = mul(worldMatrix_IT , vertexI.in_Normal).xyz;//计算顶点的法向量

    N = normalize(N);//向量规范化

 

    //计算方向光方向

    float3 L = lightPosition - worldPosition;

    L = normalize(L);//向量规范化

 

    //计算环境光漫反射光强

    float3 ambColor = Kd * globalAmbient;

 

    //计算方向光漫反射光强

    float3 dirColor = Kd * lightColor * max(dot(N , L) , 0);

 

    vertexO.out_color.rgb = ambColor + dirColor;

    vertexO.out_color.a = 1;

}

展开阅读全文

没有更多推荐了,返回首页