Lambert漫反射光照模型歸納

carbonsunsu發表於2011-12-26

此模型屬於經驗模型,主要用來簡單模擬粗糙物體表面的光照現象

此模型假設物體表面為理想漫反射體(也就是隻產生漫反射現象,也成為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;

}

相關文章