OpenGL ES系列 之 提高-3:光照

 

前面已经提到过没有光就看不见东西,无论是顶点颜色、表面材质还是纹理贴图,只有打开了光照才能看得见。

还记得下面这两行代码吗?
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
第一行窃谒怠耙泄狻保谑鞘澜缇陀泄饬恕5诙惺窃谒荡蚩?号光源,于是世界就被在默认光源(0, 0, 1.0, 0)——照向-z轴方向的平行光——白色光照亮了。

在CG世界里,我们把光照总结成几种常用模型:环境光、平行光、点光源、聚光灯。环境光是无所不在的漫射光,是场景的背景亮度。

在OpenGL ES里,没法直接定义一个无确定方向和位置的环境光源,所以忘掉在某些3D制作软件或开发工具里放置一个环境光源的经历吧。OpenGL ES的环境光是光源本身的一个属性。

平行光是指有方向但没有具体位置的光源,比如实际生活中的日光。这种光源也被称为方向光或平面光。在OpenGL ES中可以将光源位置(x,y,z,w)中的w置为0来定义平行光源。

点光源是指有具体位置,向所有方向均匀发射光线的光源,就象实际生活中的灯泡。在OpenGL ES中的光源默认就是点光源。

聚光灯是受限的点光源,只在照射方向某个角度范围之内投射光线,并且光照的强度可能与夹角有关系。在OpenGL ES中可以通过GL_SOPT_DIRECTION, GL_SPOT_CUTOFF, GL_SPOT_EXPONENT等参数来定义一个聚光灯。

现在再来看一下OpenGL ES里定义一个光源都有哪些参数可用:

光源颜色:GL_AMBIENT 环境光RGBA强度, GL_DIFFUSE 散射光RGBA强度, GL_SPECULAR 高光(镜面反射区)RGBA强度
光源位置:GL_POSITION (x,y,z,w)齐次坐标,w为0时为平行光,此时光照计算仅依赖于光源方向而与其位置无关,并且光线不进行衰减处理。
聚光性:GL_SPOT_DIRECTION 聚光灯光照方向,GL_SPOT_CUTOFF 最大发散角[0,90] 与方向夹角超过此范围的区域不会被光照到。

光照计算:
OpenGL ES里光照的效果最终表现为物体表面各点的颜色,它必然要和物体表面的材质纹理合并起来。而在同一个场景里可能有多个光源,这些光源的照明效果也需要合并。

  • 合并光照效果:
    • C = 材质的自发光(emissivemat) + 环境光强(ambientmat * ambientscene) + ∑ 反射光
    • 各光源的反射光强度计算:
      • 传播衰减系数 * 聚光衰减系数 * ( 散射光 + 漫射光 + 高光 )。
        • 传播衰减系数表示光源与物体间距d对光强的影响,OpenGL ES实际上可指定常量衰减因子k0, 线性衰减因子k1, 平方衰减因子k2,三者合起来( k0 + k1*d + k2*d2 )才是总的传播衰减系数。
        • 聚光衰减因子表达的是聚光灯的聚光特性——光锥的中心最亮,越往边缘越暗,与光线偏离中心线的角度有关。
        • 散射光 = ambientmat * ambientlight
        • 漫射光 = diffusemat * diffuselight * ( normal Vectorvertex_to_positionlight) )
        • 高光 = ( normal halfVector )specExpmat * specularmat * specularlight
          • * halfVector = Vectorlight_to_vertex + Vectorvertex_to_eye
  • * 高光部分的计算公式表明,OpenGL ES使用的是Blinn-Phong光照模型。
    如果需要使用其它模型,可以通过编程实现,不过在没有Shader支持的情况下,就利用不上硬件加速。OpenGL ES 2.0定义了可编程管线,可以编写Shader,不过我还没有见过实际支持的硬件,只有某些软件库支持。
在这个光照计算公式下,各种光源的控制如下:
  • 平行光/方向光:
    • 这种光源位置的w=0,表示从无限远处照过来,这种光是不衰减的,即物体顶点与光源之间的距离差别忽略不计。这种光源的反射光计算非常简单,光源的照射方向记为halfVectorlight,则光照效果为:
      ambient += ambientlight
      diffuse += diffuselight * (normal positionlight)
      specular += specularlight * ( normal halfVectorlight )shinessmaterial_front
    • 建立一个这样光源LIGHTi的命令序列为:
      glEnable(GL_LIGHTi)
      glLight
  • 点光源
  • 聚光灯

 

Light Lab 这是一个挺不错的光照试验程序,可以在PC上用来帮助理解OpenGL光照模型。作者只以源码的形式发行这个工具,在windows上可能需要借助 cygwin编译,或者有耐心的自己拿源码做个VC项目亦可。

未完成……

你可能感兴趣的:(WinCE,OpenGL,ES)