OpenGL学习脚印:Blinn-Phong光照模型
Posted The fool
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL学习脚印:Blinn-Phong光照模型相关的知识,希望对你有一定的参考价值。
写在前面
在前面基础光照部分,我们学习了Phong Shading模型,Blinn-Phong模型对Phong模型的镜面光成分进行了改进,虽然在物理上解释没有Phong好,但是能更好地模拟光照。本节代码可以在我的github下载。
本节内容整理自:
1.www.learnopengl.com
2.Blinn-Phong Model
Phong不能处理的情况
我们知道,Phong模型在计算镜面光系数为:
float specFactor = pow(max(dot(reflectDir, viewDir), 0.0), 32); // 32为镜面高光系数
这里的计算由反射向量和观察向量决定,当两者的夹角
θ
超过90时,截断为0.0,则没有了镜面光成分。因此Phong模型能处理的是下面的左图中(
θ≤90
)的情况,而对于右图中(
θ>90
)的情况则镜面光成分计算为0(来自Advanced-Lighting)。
而右图的这种情况实际上是存在的,将镜面光成分取为0,没有很好地体现实际光照情况。例如下面的图表示的是,镜面光系数为1.0,法向量为(0.0,1.0,0.0)的平面位置在-0.5,光源在原点时,观察者在(0,0,4.0)位置时,光照展示的情形:
这里我们看到,Phong的镜面光成分,在边缘时立马变暗,这种对比太明显,不符合实际情形。
为什么会产生这样一个光线明暗分明的情形? 我尝试这样推导,对此不感兴趣地可以跳过。
首先记表面位置为 fragPos=(x,−0.5,z) , 光源位置为 lightPos=(0.0,0.0,0.0) ,则光照向量为:
L=−(lightPos−fragPos)=(x,−0.5,z)(light direction)
法向量为:
N=(0.0,1.0,0.0)(surface normal)
根据 reflect函数的计算原理,得到反射向量为:
R=L−2.0∗dot(N,L)∗N=(x,−0.5,z)−2.0∗(−0.5)∗(0.0,1.0,0.0)=(x,0.5,z)(surface reflection)
设观察点位置为
(x′,y′,z′)
,则观察向量为:
那么反射向量和观察向量的点积为:
dot(R,V)=(xx′−x2+0.5y′+0.25+zz′−z2)=−[(x−x′2)2+(z−z′2)2−0.25(x′2+z′2+1+2y′)]
记 δ=0.25(x
以上是关于OpenGL学习脚印:Blinn-Phong光照模型的主要内容,如果未能解决你的问题,请参考以下文章
OpenGL学习脚印:伽马校正(Gamma Correction)
shader编程-RayMarching与Blinn-Phong光照模型搭建三维场景(WebGL-Shader开发基础08)
shader编程-RayMarching与SDF搭建三维场景实现Blinn-Phong光照(WebGL-Shader开发基础08)
shader编程-RayMarching与SDF搭建三维场景实现Blinn-Phong光照(WebGL-Shader开发基础08)