OpenGL中的光照模型
一、OpenGL的光照模型
在OpenGL的简单光照模型中反射光可以分成三个分量,环境反射光(Ambient Light)、漫反射光(Diffuse Light)和镜面反射光(Specular Light):
a、环境光Ambient,是由光源发出经环境多次散射而无法确定其入射方向的光,即似乎来自所有方向。当环境光照到曲面上时,它在各个方向上均等地发散(类似于无影灯光)。特征:入射方向和出射方向均为任意方向。
b、漫射光Diffuse,来自特定方向,它垂直于物体时比倾斜时更明亮。一旦它照射到物体上,则在各个方向上均匀地发散出去,效果为无论视点在哪里它都一样亮。特征:入射方向唯一、出射方向为任意方向。
c、镜面光Specular,来自特定方向并沿另一方向反射出去,一个平行激光束在高质量的镜面上产生100%的镜面反射。特征:入射方向和出射方向均唯一。
二、创建光源
定义光源特性的函数:glLight*(light , pname, param)
其中第一个参数light指定所创建的光源号,如GL_LIGHT0、GL_LIGHT1、...、GL_LIGHT7;第二个参数pname指定光源特性,这个参数的辅助信息见表1所示;最后一个参数设置相应的光源特性值。 pname 参数名 GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_POSITION GL_SPOT_DIRECTION GL_SPOT_EXPONENT GL_SPOT_CUTOFF GL_CONSTANT_ATTENUATION GL_LINER_ATTENUATION GL_QUADRATIC_ATTENUATION 缺省值 说明 (0.0, 0.0, 0.0, 1.0) RGBA模式下环境光 (1.0, 1.0, 1.0, 1.0) RGBA模式下漫反射光 (1.0,1.0,1.0,1.0) (0.0,0.0,1.0,0.0) (0.0,0.0,-1.0) 0.0 180.0 1.0 0.0 0.0 RGBA模式下镜面光 光源位置齐次坐标(x,y,z,w) 点光源聚光方向矢量(x,y,z) 点光源聚光指数 点光源聚光截止角 常数衰减因子 线性衰减因子 平方衰减因子 表1 函数glLight*()参数pname说明 注意:以上列出的GL_DIFFUSE和GL_SPECULAR的缺省值只能用于GL_LIGHT0,其他几个光源的GL_DIFFUSE和GL_SPECULAR缺省值为(0.0,0.0,0.0,1.0)。
三、启用光源和明暗处理
如果光照无效,则只是简单地将当前颜色映射到当前顶点上去,不进行法向、光源、材质等复杂计算。要启用光照或关闭光照,调用函数:glEnable(GL_LIGHTING) 或glDisable(GL_LIGHTING)。
启用光照后必须调用函数glEnable(GL_LIGHT0) ,使所定义的光源有效。其它光
源类似,只是光源号不同而已。
在OpenGL中,用单一颜色处理的称为平面明暗处理(Flat Shading),用许多不同颜色处理的称为光滑明暗处理(Smooth Shading),也称为Gourand明暗处理(Gourand Shading)。
设置明暗处理模式的函数为:glShadeModel(mode) 函数参数mode为GL_FLAT或GL_SMOOTH,分别表示平面明暗处理和光滑明暗处理。
四、光源的颜色、位置与衰减
光源的颜色由AMBIENT、DIFFUSE、SPECULAR决定。其中DIFFUSE(漫反射光)与光源的颜色最紧密;要实现真实感,应将属性SPECULAR的值设置成与DIFFUSE相同。
光源位置坐标采用齐次坐标(x, y, z, w)设置。w为0.0,相应的光源是定向光,(x, y, z)描述光源的方向,该方向将根据模型视点矩阵进行变换;w为1.0,光源为定位光源。(x, y, z, w)指定光源在齐次坐标系下的具体位置,该位置根据模型视点矩阵进行变换,保存为视点坐标系下的坐标。
离光源越远则光强越弱。由于定向光源是无穷远光源,根据距离衰减光强无意义,因此对于定向光源将禁用衰减;对于定位光源有衰减,OpenGL的光衰减是通过光源的发光量乘以衰减因子以实现衰减。
衰减系数=1/(K0+K1*D+K2*D2) 其中:
D=光源位置与顶点之间的距离 K0= GL_CONSTANT_ATTENUATION K1= GL_LINER_ATTENUATION
K1= GL_QUADRATIC_ATTENUATION
环境光、漫反射光和镜面光的强度都衰减,只有辐射光和全局环境光的强度不会衰减。由于每次计算颜色时,使用衰减的光源会增加额外的计算而可能降低应用程序的性能。
五、聚光灯
定位光源可以进一步定义成聚光灯形式,即将光的形状限制在一个圆锥内。 (1)、定义聚光截止角:
参数GL_SPOT_CUTOFF给定光锥的轴与中心线的夹角,也可说成是光锥顶角的一半。缺省时,这个参数为180.0,即顶角为 360度,光向所有的方向发射,因此聚光关闭。一般在聚光启动情况下,聚光截止角限制在[0.0, 90.0] 之间,如下面一行代码设置截止角为45度:
glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,45.0) (2)、定义聚光方向:
聚光方向决定光锥的轴,由齐次坐标定义,其缺省值为(0.0, 0.0, -1.0),即指向Z负轴。聚光方向也要进行几何变换,其结果保存为视点坐标系下的坐标。
(3)、定义聚光指数:
参数GL_SPOT_EXPONENT控制光的集中程度,光锥中心的光强最大,从轴线向母线移动时光强逐渐衰减,缺省时为0。聚光指数越大,光源的聚焦效果越好。
除了定义聚光指数控制光锥内光强的分布,还可同时利用定位光源的衰减因子的设置光强衰减。
六、光照模型属性
OpenGL的光照模型属性包括四项内容:(1)全局环境光强度;(2)观察点靠近场景还是位于无穷远处;(3)对物体的正面和背面是否采取相同的光照计算;(4)是否将镜面反射颜色同环境颜色和散射颜色分开。
(1)、全局环境光:
每个光源都能对一个场景提供环境光,此外还有一个环境光,它不来自任何特定的光源,即称为全局环境光。用函数glLightModelfv()和参数GL_LIGHT_MODEL_AMBIENT来设定全局环境光的RGBA强度如下:
Dim lmodel_ambient() As Single={0.2,0.2,0.2,1.0} RGBA颜色值 glLightModelfv(GLLIGHT_MODEL_AMBIENT,lmodel_ambient)
在这个例子中,lmodel_ambient所用的值为GL_LIGHT_MODEL_AMBIENT的缺省值。这些数值产生小量的白色环境光。因此即使场景中没有任何光源也能看到场景中的物体。
(2)、近视点与无穷远视点:
视点位置能影响镜面高光的计算,也就是说,顶点的高光强度依赖于顶点法向量,从顶点到光源的方向和从顶点到视点的方向。实际上,调用光照函数并不能移动视点。但是可以对光照计算作出不同的假定,这样视点似乎移动了。对于一个无穷远视点,视点到任何顶点的方向保持固定,缺省时为无穷远视点。对于一个近视点,物体每个顶点到视点的方向是不同的,需要逐个计算,从而整体性能降低,但效果更真实。
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE)
这个调用把视点放在视点坐标系的原点处。若要切换到无穷远视点,只需将参数GL_TRUE 改为GL_FALSE即可。
(3)、 双面光照:
光照计算通常是对所有多边形进行的,无论其是正面或反面。一般情况下,设置光照条件时总是正面多边形,因此不能对背面多边形进行正确地光照。启动双面光照,调用如下函数:
glLightModeli(LIGHT_MODEL_TWO_SIDE,GL_TRUE)
七、材质
OpenGL用材料对光的红、绿、蓝三原色的反射率来近似定义材料的颜色。象光源一样,材料颜色也分成环境、漫反射和镜面反射分量,它们决定了材料对环境光、漫反射光和镜面反射光的反射程度,材料对环境光与漫反射光的反射程度决定了材料的颜色。
材质的颜色与光源的颜色有些不同。对于光源,R、G、B值等于R、G、B对其最大强度的百分比。若光源颜色的R、G、B值都是1.0,则是最强的白光;若值变为0.5,颜色仍为白色,但强度为原来的一半,于是表现为灰色。对于材质,R、G、B值为材质对光的 R、G、B成分的反射率。比如,一种材质的R=1.0、G=0.5、B=0.0,则材质反射全部的红色成分,一半的绿色成分,不反射蓝色成分。即若OpenGL的光源颜色为(LR、LG、LB),材质颜色为(MR、MG、MB),那么,在忽略所有其他反射效果的情况下,最终到达眼睛的光的颜色为(LR*MR、LG*MG、LB*MB)。
材质的定义函数为:glMaterial*(face, pname, param)
其中第一个参数face可以是GL_FRONT、GL_BACK、GL_FRONT_AND_BACK,它表明当前材质应该应用到物体的哪一个面上;pname说明材质的特性;第二个参数pname指定材质特性,这个参数的辅助信息见表2所示;最后一个参数设置相应的材质特性值,若函数为向量形式,则param是数组的指针,反之为参数值本身。
参数GL_AMBIENT_AND_DIFFUSE表示可以用相同的 RGB值设置环境光颜色和漫反射光颜色。 pname参数名 GL_AMBIENT GL_DIFFUSE 缺省值 (0.2, 0.2, 0.2, 1.0) (0.8, 0.8, 0.8, 1.0) 说明 材料的环境光颜色 材料的漫反射光颜色 材料的环境光和漫反射光颜色 材料的镜面反射光颜色 镜面指数(光亮度) 材料的辐射光颜色 材料的环境光、漫反射光和镜面光颜色 GL_AMBIENT_AND_DIFFUSE GL_SPECULAR GL_SHININESS GL_EMISSION GL_COLOR_INDEXES (0.0, 0.0, 0.0, 1.0) 0.0 (0.0, 0.0, 0.0, 1.0) (0, 1, 1) 表2 函数glMaterial*()参数pname的缺省值
八、辐射光
通过GL_EMISSION给材质定义一个RGBA值,可以使物体看起来象发出这种 颜色的光一样,以达到某种特殊效果。实际上,现实生活中的物体除光源外都不发光,但我们可以利用这一特性来模拟灯和其他光源。代码举例如下
Dim mat_emission() As Single={0.3,0.3,0.5,0.0}
glMaterialfv(GL_FRONT,GL_EMISSION,mat_emission)
这样,物体看起来稍微有点发光。比如绘制一个打开的台灯,就可以将一个小球的材质定义成上述形式,并且在小球内部建立一个聚光源,这样台灯的灯泡效果就出来了。
百度搜索“70edu”或“70教育网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,70教育网,提供经典教育范文OpenGL中的光照模型在线全文阅读。
相关推荐: