Phong和Blinn-Phong光照模型
2016-03-20 19:43
375 查看
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’。总结一下就是下面的公式:
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的顶点和片段着色程序
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’。总结一下就是下面的公式:
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
structV2F{ float4position:POSITION; float3worldPosition:TEXCOORD0; float3worldNormal:TEXCOORD1; }; voidPhong_FragmentLighting_v(float4position:POSITION, float4normal:NORMAL, uniformfloat4x4modelMatrix, uniformfloat4x4modelMatrix_IT, uniformfloat4x4modelViewProj, outV2FO){ O.position=mul(modelViewProj,position); O.worldPosition=mul(modelMatrix,position).xyz; O.worldNormal=normalize(mul(modelMatrix_IT,normal)).xyz; }
Phong_FragmentLighting_f.cg
voidPhong_FragmentLighting_f(float3position:TEXCOORD0, float3normal:TEXCOORD1, uniformfloat3globalAmbient, uniformfloat3lightColor, uniformfloat3lightPosition, uniformfloat3eyePosition, uniformfloat3Ke, uniformfloat3Ka, uniformfloat3Kd, uniformfloat3Ks, uniformfloatshininess, outfloat4color:COLOR) { float3N=normalize(normal); float3L=normalize(lightPosition-position); float3V=normalize(eyePosition-position); float3R=reflect(-L,N); R=normalize(R); //Computeemissiveterm float3emissive=Ke; //Computeambientterm float3ambient=Ka*globalAmbient; //Computethediffuseterm floatdiffuseLight=max(dot(N,L),0); float3diffuse=Kd*lightColor*diffuseLight; //Computethespecularterm floatspecularLight=pow(max(dot(V,R),0),shininess); if(diffuseLight<=0)specularLight=0; float3specular=Ks*lightColor*specularLight; //color.xyz=emissive+ambient+diffuse+specular; color.xyz=ambient+diffuse+specular; color.w=1; }
BlinnPhong_FragmentLighting_v.cg
structV2F{ float4position:POSITION; float3worldPosition:TEXCOORD0; float3worldNormal:TEXCOORD1; }; voidBlinnPhong_FragmentLighting_v(float4position:POSITION, float4normal:NORMAL, uniformfloat4x4modelMatrix, uniformfloat4x4modelMatrix_IT, uniformfloat4x4modelViewProj, outV2FO){ O.position=mul(modelViewProj,position); O.worldPosition=mul(modelMatrix,position).xyz; O.worldNormal=normalize(mul(modelMatrix_IT,normal)).xyz; }
BlinnPhong_FragmentLighting_f.cg
voidBlinnPhong_FragmentLighting_f(float3position:TEXCOORD0,
float3normal:TEXCOORD1,
uniformfloat3globalAmbient,
uniformfloat3lightColor,
uniformfloat3lightPosition,
uniformfloat3eyePosition,
uniformfloat3Ke,
uniformfloat3Ka,
uniformfloat3Kd,
uniformfloat3Ks,
uniformfloatshininess,
outfloat4color:COLOR)
{
float3N=normalize(normal);
float3L=normalize(lightPosition-position);
float3V=normalize(eyePosition-position);
float3H=normalize(L+V);
//Computeemissiveterm
float3emissive=Ke;
//Computeambientterm
float3ambient=Ka*globalAmbient;
//Computethediffuseterm
floatdiffuseLight=max(dot(N,L),0);
float3diffuse=Kd*lightColor*diffuseLight;
//Computethespecularterm
floatspecularLight=pow(max(dot(H,N),0),shininess);
if(diffuseLight<=0)specularLight=0;
float3specular=Ks*lightColor*specularLight;
color.xyz=ambient+diffuse+specular;
color.w=1;
}
效果对比:
Phong光照模型
Blinn-Phong光照模型
通过简单的对比发现,在相同条件下Blinn-Phong的高光范围要比Phong更大,写实效果Phong光照模型更好。但算法简单,运行速度快是Blinn-Phong光照模型的优点。
相关文章推荐
- 《leetCode》:Contains Duplicate II
- hdu 4311 Meeting point-1 (快速求解曼哈顿距离和)
- iOS开发------实现图片下载缓存到本地
- Linux基础知识学习
- 两个解释动态规划问题非常直观形象的例子
- 广义后缀自动机与后缀树
- hud5040 InstrusiveBFS+优先队列
- JavaScript中的typeof和instanceof
- 不使用库函数实现字符串处理函数
- C语言-知识点及学习路线
- 构建之法前三章读后感
- 一元多项式及其运算
- Linux内核协议栈(2) 由简单的socket编程例子开始
- web前端的三个重要部分
- 【牛腩小试】——IIS配置
- 5-26单词长度
- 进程的概念
- 正确实现浅拷贝和深拷贝
- 猎豹MFC--枚举进程4种方法1
- SGI的特殊空间配置器