【转】Phong和Blinn-Phong光照模型
【轉】Phong和Blinn-Phong光照模型
來自:http://www.cnblogs.com/bluebean/p/5299358.html
Phong和Blinn-Phong是計算鏡面反射光的兩種光照模型,兩者僅僅有很小的不同之處。
?
1.Phong模型
Phone模型計算中的一個關鍵步驟就是反射向量R的計算:
?
上圖中的位于表面“下面”的向量?‘I’?是原始?‘I’?向量的拷貝,并且二者是一樣的,現在我們的目標計算出向量?‘R’?。根據向量相加原則,向量?‘R’?等于?'I'?+?'V',‘I’?是已知的,所以我們需要做的就是找出向量?‘V’。注意法向量?‘N’?的負方向就是?‘-N’,我們可以在?‘I’?和?‘-N’?之間使用一個點乘運算就能得到?‘I’?在?‘-N’?上面的投影的模。這個模正好是?‘V’?的模的一半,由于?‘V’?與?‘N’?有相同的方向,我們可以將這個模乘上?‘N’?(其模為?1?)再乘上?2?即可得到?‘V’??偨Y一下就是下面的公式:
?
?
2.Blinn-Phong模型
?Phong模型中計算反射光線的向量是一件相對比較耗時的任務,因此Blinn-Phong對這一點進行了改進。
?
Ks:物體對于反射光線的衰減系數
N:表面法向量
H:光入射方向L和視點方向V的中間向量
Shininess:高光系數
?
可見,通過該式計算鏡面反射光是符合基本規律的,當視點方向和反射光線方向一致時,計算得到的H與N平行,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光照模型的優點。
posted on 2018-08-14 11:53 時空觀察者9號 閱讀(...) 評論(...) 編輯 收藏
總結
以上是生活随笔為你收集整理的【转】Phong和Blinn-Phong光照模型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2018.8.14-C#复习笔记总
- 下一篇: 一本很好的书LearnOpenGL