OpenGL ES 学习教程(10.2):Point Light(定点光)

发表于2017-11-22
评论0 2.3k浏览


定点光,就是光源的位置固定的光!在前面的文章中已经有所提及,也是本篇文章要重点和大家介绍的对象。但是在前面学习的光照中,都是假设灯光没有衰减的,不管多远,物体受到的光照都是强度相同的。但是现实中,灯光不可能照亮很远的地方,在一个范围之内就会完全消失在黑暗之中。



衰减(Autenuation)


光的亮度,随着远离光源的距离而越来越弱。 开始的时候减少的很快,然后随着距离的增加慢慢变弱。

幸好我们有一个公式可以借鉴


I     :代表的是 光源的光照强度,一般设置为 1.0f 。

Kc :代表常量

Kl  :一次项

Kq :二次项

d    :与光源的距离

从公式中可以看出,随着 d 的增大,Fatt 不断变小。


而且对于 Kc、Kl、Kq 、d 我们也有对应的数据来参考,这是来自OGRE3D的光的衰减参数表。




好了,下面我们来代码实现。

仍然以 高光贴图 那一篇的例子来作为基础。


首先要在 Fragment Shader 中添加 三个参数 Kc、Kl、Kq ( GLProgram_Cube.h Line 120 )

"struct Light"  //替换光的RGB分量强度  
"{"  
"       vec3 position;"  
"       vec3 ambient;"  
"       vec3 diffuse;"  
"       vec3 specular;"  
"       float constant;"//常量;  
"       float linear;"      //一次项;  
"       float quadratic;" //二次项;  
"};"  
"uniform Light m_light;"  

然后 使用 GLSL 内置函数 length 来计算两个点的距离。( GLProgram_Cube.h Line 143 )
"   float distance = length(m_light.position - out_fragpos);"//计算向量的长度;  
然后计算 衰减 Autenuation ( GLProgram_Cube.h Line 144 )
"   float attenuation = 1.0 / (m_light.constant + m_light.linear * distance + m_light.quadratic*(distance*distance));"  

然后把 衰减值 与 Ambient 、 Diffuse 、 Specular 相乘,得到最终的衰减的光照。( GLProgram_Cube.h Line 146 )
"   vec3 result=ambient*attenuation +diffuse*attenuation+specular*attenuation;" //(环境光+漫反射光) * 物体本身的颜色   

然后需要在 代码中 传入  三个参数 Kc、Kl、Kq 的值。

//设置衰减系数;  
glUniform1f(m_programCube.m_lightConstant, 1.0f);  
glUniform1f(m_programCube.m_lightLiner, 0.045f);  
glUniform1f(m_programCube.m_lightQuadratic, 0.0075f);  

这一次我绘制了两个 Cube 用来,一个位于 glm::vec3(0.0f, 0.0f, 0.0f) ,另一个位于 glm::vec3(0.0f, 0.0f, -5.0f) 。

而且我把 光源 和 相机 设置为同一个位置 glm::vec3(-2, 0, 10) 。

最后得到的效果


可以看到,距离较远的 Cube 明显比 距离近的 Cube 暗了许多。这就是光的衰减。


下图是没有衰减的 效果,对比一下:

如果没有衰减,这两个 Cube 虽然远近不同,但是受到的光照强度却是一样的。


例子工程打包下载:http://pan.baidu.com/s/1jHlnZ06

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引