Phong和Blinn-Phong光照模型

PhongBlinn-Phong是計算鏡面反射光的兩種光照模型,二者僅僅有很小的不一樣之處。算法

 

1.Phong模型spa

Phone模型計算中的一個關鍵步驟就是反射向量R的計算:3d

 

上圖中的位於表面下面的向量 ‘I’ 是原始 ‘I’ 向量的拷貝,而且兩者是同樣的,如今咱們的目標計算出向量 ‘R’ 。根據向量相加原則,向量 ‘R’ 等於 'I' + 'V'‘I’ 是已知的,因此咱們須要作的就是找出向量 ‘V’。注意法向量 ‘N’ 的負方向就是 ‘-N’,咱們能夠在 ‘I’ 和 ‘-N’ 之間使用一個點乘運算就能獲得 ‘I’ 在 ‘-N’ 上面的投影的模。這個模正好是 ‘V’ 的模的一半,因爲 ‘V’ 與 ‘N’ 有相同的方向,咱們能夠將這個模乘上 ‘N’ (其模爲 )再乘上 便可獲得 ‘V’。總結一下就是下面的公式:code

 

 

2.Blinn-Phong模型orm

 Phong模型中計算反射光線的向量是一件相對比較耗時的任務,所以Blinn-Phong對這一點進行了改進。blog

 

Ks:物體對於反射光線的衰減係數it

N:表面法向量io

H:光入射方向L和視點方向V的中間向量form

Shininess:高光係數class

 

可見,經過該式計算鏡面反射光是符合基本規律的,當視點方向和反射光線方向一致時,計算獲得的HN平行,dot(N,H)取得最大;當視點方向V偏離反射方向時,H也偏離N

同時H的計算比起反射向量R的計算簡單的多,R向量的計算須要若干次的向量乘法與加法,而H的計算僅僅須要一次加法。

下面是用cg着色語言書寫的Phong和Blinn-Phong的頂點和片斷着色程序

 

Phong_FragmentLighting_v.cg

 

 

 1 struct V2F{
 2     float4 position:POSITION;
 3     float3 worldPosition: TEXCOORD0;
 4     float3 worldNormal :TEXCOORD1;
 5 };
 6 void Phong_FragmentLighting_v(float4 position :POSITION,
 7                               float4 normal:NORMAL,
 8                               uniform float4x4 modelMatrix,
 9                               uniform float4x4 modelMatrix_IT,
10                               uniform float4x4 modelViewProj,
11                               out V2F O){
12     O.position=mul(modelViewProj,position);
13     O.worldPosition=mul(modelMatrix,position).xyz;
14     O.worldNormal=normalize(mul(modelMatrix_IT,normal)).xyz;
15 }

 

Phong_FragmentLighting_f.cg
 1 void Phong_FragmentLighting_f(float3 position :TEXCOORD0,
 2                                float3 normal: TEXCOORD1,
 3                                uniform float3 globalAmbient,
 4                                uniform float3 lightColor,
 5                                uniform float3 lightPosition,
 6                                uniform float3 eyePosition,
 7                                uniform float3 Ke,
 8                                uniform float3 Ka,
 9                                uniform float3 Kd,
10                                uniform float3 Ks,
11                                uniform float  shininess,
12                                out float4 color:COLOR)
13               {
14                   float3 N=normalize(normal);
15                   float3 L=normalize(lightPosition-position);     
16                   float3 V=normalize(eyePosition-position);
17                   
18                   float3 R=reflect(-L,N);
19                   R=normalize(R);
20                   
21                   // Compute emissive term
22                   float3 emissive = Ke;
23 
24                  // Compute ambient term
25                  float3 ambient = Ka * globalAmbient;
26 
27                 // Compute the diffuse term
28                 float diffuseLight = max(dot(N, L), 0);
29                 float3 diffuse = Kd * lightColor * diffuseLight;
30 
31                 // Compute the specular term
32                 float specularLight = pow(max(dot(V, R), 0), shininess);
33                 if (diffuseLight <= 0) specularLight = 0;
34                 float3 specular = Ks * lightColor * specularLight;
35 
36                 //color.xyz = emissive + ambient + diffuse + specular;
37                 color.xyz=ambient + diffuse + specular;
38                 color.w = 1;
39               }
BlinnPhong_FragmentLighting_v.cg
 1 struct V2F{
 2     float4 position:POSITION;
 3     float3 worldPosition: TEXCOORD0;
 4     float3 worldNormal :TEXCOORD1;
 5 };
 6 void BlinnPhong_FragmentLighting_v(float4 position :POSITION,
 7                               float4 normal:NORMAL,
 8                               uniform float4x4 modelMatrix,
 9                               uniform float4x4 modelMatrix_IT,
10                               uniform float4x4 modelViewProj,
11                               out V2F O){
12     O.position=mul(modelViewProj,position);
13     O.worldPosition=mul(modelMatrix,position).xyz;
14     O.worldNormal=normalize(mul(modelMatrix_IT,normal)).xyz;
15 }
 
BlinnPhong_FragmentLighting_f.cg
 1 void BlinnPhong_FragmentLighting_f(float3 position :TEXCOORD0,
 2                                float3 normal: TEXCOORD1,
 3                                uniform float3 globalAmbient,
 4                                uniform float3 lightColor,
 5                                uniform float3 lightPosition,
 6                                uniform float3 eyePosition,
 7                                uniform float3 Ke,
 8                                uniform float3 Ka,
 9                                uniform float3 Kd,
10                                uniform float3 Ks,
11                                uniform float  shininess,
12                                out float4 color:COLOR)
13               {
14                   float3 N=normalize(normal);
15                   float3 L=normalize(lightPosition-position);     
16                   float3 V=normalize(eyePosition-position);
17                   
18                  float3 H=normalize(L+V);
19                   
20                   // Compute emissive term
21                   float3 emissive = Ke;
22 
23                  // Compute ambient term
24                  float3 ambient = Ka * globalAmbient;
25 
26                 // Compute the diffuse term
27                 float diffuseLight = max(dot(N, L), 0);
28                 float3 diffuse = Kd * lightColor * diffuseLight;
29 
30                 // Compute the specular term
31                 float specularLight = pow(max(dot(H, N), 0), shininess);
32                 if (diffuseLight <= 0) specularLight = 0;
33                 float3 specular = Ks * lightColor * specularLight;
34 
35                 color.xyz=ambient + diffuse + specular;
36                 color.w = 1;
37               }

效果對比:


Phong光照模型
Blinn-Phong光照模型經過簡單的對比發現,在相同條件下Blinn-Phong的高光範圍要比Phong更大,寫實效果Phong光照模型更好。但算法簡單,運行速度快是Blinn-Phong光照模型的優勢。
相關文章
相關標籤/搜索