OpenGL ES 学习教程(10.1):Directional Light(平行光)

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

前面我们学习光照的时候,指定了灯光的所在位置。根据灯光的位置与Fragment的位置算出向量A,然后与Fragment 的法线进行计算,得到夹角,然后计算出 Fragment 受光照的强弱大小。


指定灯光位置的方式常见于室内的灯泡、手电筒等环境。




对于太阳及其它类似的发光体,我们可以作为平行光(Directional Light) 来处理。



我们拿上篇OpenGL ES 学习教程(9):油腻的效果Lighting Maps高光贴图的工程来进行修改。


在上一节 高光贴图 中,是指定了光源的位置,现在修改成 直接指定  光线方向。


修改 GLProgram_Cube.h Line115 ,去掉 position ,添加 direction 。

"struct Light"  //替换光的RGB分量强度  
"{"  
//"     vec3 position;"  
"       vec3 direction;"  
"       vec3 ambient;"  
"       vec3 diffuse;"  
"       vec3 specular;"  
"};"  
"uniform Light m_light;"  

然后 原来的计算 由 Fragment 指向 灯光位置的向量,也不必进行了。

修改 GLProgram_Cube.h Line127 。

"   vec3 normal=normalize(out_normal);"                            //法线向量 A  
//" vec3 lightdir=normalize(m_light.position-out_fragpos);"     //物体指向灯光 向量  B  
"   vec3 lightdir=normalize(-m_light.direction);"  
"   float cosvalue=max( dot(normal,lightdir),0.0);" //点乘A B 计算角度cos值,角度越大 cos越小,90度的时候法线和光垂直,最小值。  
"   vec3 diffuse=(cosvalue* vec3(texture2D(m_diffusetexture,m_outUV))*m_light.diffuse);"  //漫反射光  
"   vec3 cameraDir=normalize(m_camerapos-out_fragpos);" //计算顶点片段指向观察者的向量  
"   vec3 reflectDir=reflect(-lightdir,normal);" //计算光的反射 R reflect第一个参数是光源指向片段的向量  
"   float spec=pow(max(dot(cameraDir,reflectDir),0.0),m_material.shininess);" //计算镜面亮度,32是高光的发光值 Shininess,发光值越高,反射光越强,散射越小,高光点越集中。  
"   vec3 specular=(spec * vec3(texture2D(m_speculartexture,m_outUV))*m_light.specular);"  
"   vec3 result=ambient +diffuse+specular;" //(环境光+漫反射光) * 物体本身的颜色  


然后传入 direction 的值。

修改 GLProgram_Cube.h Line161。

m_lightDirection = glGetUniformLocation(m_programId, "m_light.direction");  


修改 MyApp.h Line143

glUniform3f(m_programCube.m_lightDirection, 0.0f, 0.0f, -1.0f);//传入光的方向.照向屏幕里面,照亮正面;  


运行效果图:


可以看到,每个箱子上面受到的光照都是相同的!!


实例工程下载:http://pan.baidu.com/s/1i4bfphb 

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