OpenGL ES 学习教程(10.2):Point Light(定点光)
发表于2017-11-22
定点光,就是光源的位置固定的光!在前面的文章中已经有所提及,也是本篇文章要重点和大家介绍的对象。但是在前面学习的光照中,都是假设灯光没有衰减的,不管多远,物体受到的光照都是强度相同的。但是现实中,灯光不可能照亮很远的地方,在一个范围之内就会完全消失在黑暗之中。
衰减(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