4.1、环境光、漫反射光、镜面反射光
OpenGLES灯光模拟由每个光源的三个截然不同的部分组成:环境光、漫反射光、镜面反射光。程序会分别配置每个部分的颜色。图4-2显示的是模拟灯光的每个部分的效果。环境光来自各个方向,因此会同等地增强所有几何图形的亮度。程序通过设置模拟环境光的颜色和亮度来设置场景中的背景灯光的基础水平。环境光的颜色会着色所有的几何图形,因此一个红色的环境光会让一个场景中的所有几何图形对象显现红色或者 粉红色。每个光源的漫反射部分是定向的,会基于三角形相对于光线的方向来照亮场景中的每个三角形。如果一个三角形的平面垂直于光线的方向,那么漫反射光会直接投射到三角形上,并被剧烈地散射开来,这会让三角形显得灯光通明。如果三角形的平面是平行于光线的方向或者背离光线的方向,那么几乎没有任何光线会照射到三角形上,因此漫反射光很少或者根本不会对三角形的亮度产生影响。漫反射光的颜色只会着色被定向的光线照射到的三角形。最后从几何图形对象反射出来的光线叫做镜面反射光。镜面物体会反射大量的光线,但是钝面的物体不会。因此镜面反射光的感知亮度是由照射到每个三角形上的光线的量和三角形的反光度决定的。镜面反射部分的颜色决定了闪光点的颜色。

图4-2描述了射向一个平面的光线。箭头指示了光线的方向。图片还表明每个平面:有两个面:一个面向光源的前面和一个背离光源的后面。一个渲染的三角形中的每个光线组成部分的效果取决于三个相互关联的因素:光线的设置、三角形相对于光线的方向,以及三角形的材质属性。OpenGLES使用术语材质 来描述三角形的一个属性,这个属性会影响三角形与光线的各个组成部分之间的相互作用。反射或散射的光线越多,三角形看起来就会越灯光通明。高反射率的镜面反射光会让三角形显现类似镀铬或者镜面的光泽。低镜面反射率会呈现--个类似于尘土和地毯的钝的材料的错觉。
只有每个光源的环境光部分才会照射三角形的后面。一些OpenGLES实现支持双面灯光的选项,就是三角形的前面和后面分别有不同的材质,但是iOs 5不支持这个选项。
注意 材质对于呈 现高度逼真的场景是非常重要的。人类无法直接看到一个光源发出的光,除非看向光源。我们可以感知到周围的物体是因为一定量的光线经过环境中的每一个对象的反射后进入了人眼。因此,我们通常看到的光是已经与材质相互作用后的光。但是,就像现实中的物体很少是由单一颜色的三角面组成的一样,现实物体很少只有一个材质,而且真实的材质往往要比OpenGL ES灯光模拟能够复制的材质要复杂得多。OpenGL ES灯光模拟仅仅靠自己是不足以渲染出一个带有磨损痕迹的光泽球或者一个泛着油光的水泥路面的。尤其需要知道的是材质是由OpenGL ES支持以用在一个程癖需要利用逼真的动态灯光绘制一个闪亮的水晶花瓶时,但是在绝大多数的程序中应该将材质设置为默认值,并使用纹理来产生想要的效果。
OpenGLES_Ch4_1示例程序演示了怎样使用苹果的iOS5中的GLKit来开启和配置OpenGL ES 2.0灯光。灯光是OpenGL ES 1.x与OpenGL ES 2.0完全不同的一个地方。早期的版本至少支持8个并存的灯光。相比普通应用以前使用的,在OpenGLES1.x中存在更多的选项和配置可能。OpenGLES2.0根本不会直接地支持任何的灯光。作为替代,运行在GPU上的自定义ShadingLanguage程序可以自由地以任何适合应用 的方式来实现光线计算。GPU能够快速地执行4.2节介绍的灯光运算,但是灯光模拟仍然会增加计算机消耗。GLKit的GLKBaseEffect类会自动地生成用于复制OpenGLES1.x为至少三个灯光所做的光线计算的Shading Language程序。如果可能的话,只使用一个光源或者不使用光源是比较好的。在第4.5节会解释使用最少的消耗来渲染出最逼真的灯光效果的最常用的技术。