您好,欢迎访问三七文档
OpenGL点光源在OpenGL场景描述中可以包含多个点光源,光源的各种属性设置使用函数:voidglLight{if}(GLenumlight,GLenumpname,TYPEparam);voidglLight{if}v(GLenumlight,GLenumpname,TYPE*param);指定。其中,参数light指定进行参数设置的光源,其取值可以是符号常量GL_LIGHT0,GL_LIGHT1,…,GL_LIGHT7;参数pname指定对光源设置何种属性,其取值参见表10-1;参数param指定对于光源light的pname属性设置何值,非矢量版本中,它是一个数值,矢量版本中,它是一个指针,指向一个保存了属性值的数组。表10-1参数pname的取值及其含义(1)点光源的颜色点光源的颜色由环境光、漫反射光和镜面光分量组合而成,在OpenGL中分别使用GL_AMBIENT、GL_DIFFUSE和GL_SPECULAR指定。其中,漫反射光成分对物体的影响最大。(2)点光源的位置和类型点光源的位置使用属性GL_POSITION指定,该属性的值是一个由4个值组成的矢量(x,y,z,w)。其中,如果w值为0,表示指定的是一个离场景无穷远的光源,(x,y,z)指定了光源的方向,这种光源被称为方向光源,发出的是平行光;如果w值为1,表示指定的是一个离场景较近的光源,(x,y,z)指定了光源的位置,这种光源称为定位光源。(3)聚光灯当点光源定义为定位光源时,默认情况下,光源向所有的方向发光。但通过将发射光限定在圆锥体内,可以使定位光源变成聚光灯。属性GL_SPOT_CUTOFF用于定义聚光截止角,即光锥体轴线与母线之间的夹角,它的值只有锥体顶角值的1/2。聚光截止角的默认值为180.0,意味着沿所有方向发射光线。除默认值外,聚光截止角的取值范围为[0.0,90.0]。GL_SPOT_DIRECTION属性指定聚光灯光锥轴线的方向,其默认值是(0.0,0.0,-1.0),即光线指向z轴负向。而GL_SPOT_EXPONENT属性可以指定聚光灯光锥体内的光线聚集程度,其默认值为0。在光锥的轴线处,光强最大,从轴线向母线移动时,光强会不断衰减,衰减的系数是:轴线与照射到顶点的光线之间夹角余弦值的聚光指数次方。(4)光强度衰减属性GL_CONSTANT_ATTENUATION、GL_LINEAR_ATTENUATION、GL_QUADRATIC_ATTENUATION分别指定了衰减系数c0,c1和c2,用于指定光强度的衰减。在OpenGL中,必须明确启用或禁用光照。默认情况下,不启用光照,此时使用当前颜色绘制图形,不进行法线矢量、光源、光照模型、材质属性的相关的计算。要启用光照,可以使用函数:glEnable(GL_LIGHTING);指定了光源的参数后,需要使用函数:glEnable(light);启用light指定的光源。当然也可以用light参数调用glDisable函数,禁用light指定的光源。需要特别说明的是,点光源的位置和方向是定义在场景中的,与景物一起通过几何变换和观察变换变换到观察坐标系中,因此光源既可以与场景中对象的相对位置保持不变,也可以使光源随观察点一起移动。OpenGL全局光照在OpenGL中,还需要设定全局光照(相当于背景光)。OpenGL提供了下面的函数对全局光照的属性进行定义。voidglLightMode{if}(GLenumpname,TYPEparam);voidglLightMode{if}v(GLenumpname,TYPE*param);其中,参数pname指定全局光照的属性,其取值参见表10-2;参数param指定进行设置的属性的值。表10-2参数pname的取值及含义属性GL_LIGHT_MODEL_AMBIENT指定OpenGL场景中的背景光,如果不指定,系统使用低强度的白色(0.2,0.2,0.2,1.0)光。镜面反射时需要几个矢量参数,包括从物体表面到观察位置的矢量V,它指出表面位置与观察位置的关系。矢量V的默认方向为正z方向(0.0,0.0,1.0),如果不希望用默认值而使用位于观察坐标原点的实际观察位置来计算V,则将GL_LIGHT_MODEL_LOCAL_VIEWER属性值指定为GL_TRUE。在有些应用中,需要看到物体的后向面,例如实体的内部剖视图。此时需要打开双面光照,即对物体的前向面和后向面都进行光照计算。在光照计算中,通常是分别计算环境光、表面散射光、漫反射光和镜面反射光的贡献,然后将其叠加。默认情况下,纹理映射在光照处理之后进行。但这样镜面高光区的纹理图案会变得不太理想。为此,可以将GL_LIGHT_MODEL_COLOR_CONTROL指定为GL_SEPARATE_SPECULAR_COLOR,在纹理映射之后应用镜面颜色。这样,对于光照计算将生成两个颜色:镜面反射颜色和非镜面反射颜色。纹理图案先和非镜面反射颜色混合,然后再和镜面反射颜色混合。OpenGL表面材质在启用了光照后,物体表面的颜色将由照射在其上的光的颜色以及物体的材质属性决定。所谓物体的材质属性,就是物体表面对各种光的反射系数。在OpenGL中使用下面的函数设定:voidglMaterial{if}(GLenumface,GLenumpname,TYPEparam);voidglMaterial{if}v(GLenumface,GLenumpname,TYPE*param);其中,face的取值可以是符号常量GL_FRONT,GL_BACK,GL_FRONT_AND_BACK,指定当前设定的材质属性应用于物体表面的前向面、后向面还是前后向面,这使得可以对物体内外表面设置不同的材质属性,在打开双面光照的情况下产生特殊的效果。参数pname指定设置的材质属性,其取值参见表10-3;参数param设置属性的值。表10-3参数pname的取值及含义属性GL_AMBIENT和GL_DIFFUSE的值定义了物体表面对环境光和漫射光中R,G,B颜色分量的反射系数。如果使用属性GL_AMBIENT_AND_DIFFUSE,那么物体表面的环境光和漫射光将使用相同的反射系数。镜面反射可以在物体表面形成高光区域。OpenGL中通过改变属性GL_SPECULAR的值改变物体表面对镜面反射光的反射率,还可以通过属性GL_SHININESS的值改变高光区域的形状和大小。GL_SHININESS属性值的取值范围为[0.0,128.0],值越大,高光区域越小、光线集中程度越高。在很多的应用中,有时希望物体亮一些,特别是对于一些表示光源的物体,此时可以通过GL_EMISSION属性使物体表面看起来有点发光。在设定了材质属性之后,物体的最终颜色是由其材质属性的RGB值和光照属性的RGB值共同决定的。例如,如果当前环境光源的RGB值为(0.5,1.0,0.5),而物体材质的环境反射系数为(0.5,0.5,0.5),那么物体表面的环境光颜色为:(0.5×0.5,1.0×0.5,0.5×0.5)=(0.25,0.5,0.25)即将每个环境光源的成分与材质的环境反射率相乘。这样,物体表面的颜色为多项RGB值的叠加:包括材质对环境光的反射率与环境光结合的RGB值,材质对漫反射光的反射率与漫反射光结合的RGB值,材质对镜面光的反射率与镜面反射光结合的RGB值等。当叠加的RGB中任何一个颜色分量的值大于1.0,那么就用1.0计算。但是,在这种设定下,有时很难判断出物体在光照环境中的颜色,为此OpenGL提供了另一种材质模式,即颜色材质模式,可以通过函数:voidglColorMaterial(GLenumface,GLenummode);设置。其中,参数face可以取GL_FRONT,GL_BACK,GL_FRONT_AND_BACK,指定物体的哪个面的材质属性使用颜色材质模式;而参数mode允许的取值是GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR、GL_AMBIENT_AND_DIFFUSE或GL_EMISSION,指定将更新哪种材质属性。在使用了颜色材质模式后,需要调用:glEnable(GL_COLOR_MATERIAL);这样,可以通过glColor函数来指定物体表面的颜色,而相应的材质属性将通过颜色值和光源的RGB值计算出来。光照效果是光线与表面共同作用的结果。在OpenGL中,光线被假定成红绿蓝三种原色光的组合,因此,光源的颜色就由它所发出的这三种原色光的含量决定,而物理表面的颜色则由其反射的这三种光的含量决定。OpenGL的光照模型尽管只是一个近似,但它很管用且计算速度很快。如果你需要一个更精确的模型,那么只好自己编程计算了,不过模型越精确则计算速度越慢。在场景中,OpenGL可以放置若干个光源,每个光源都可以被单独地打开或关闭。照在物体上的光线有些是直接来自光源,而另一些是光源的光经过若干次反射而来。这些多次反射的光被称为环境光(AmbientLight),它们已经变得很“散”,以致于无法确定其初始方向,不过当某个光源(产生它们的光源)被关闭后,它们也就消失了。不同的物理表面对光线有不同的反射特性,那些通常看起来很光泽的表面能够将入射光很好地向某一特定方向反射,而另外一些则将入射光均衡地散射向各个方向。大部分表面的特性是介于这两者之间的。当然有些表面也会自己发光,比如汽车前灯。§6.1.1光照分量OpenGL对光照效果的计算是由四个独立的部分叠加而成的,它们是:出射光[自发光](emitted)、环境光(ambient)、漫反射光(diffuse)、镜面光(specular)。出射光是最简单的,它从物体发出且不受任何其它光源的影响。环境光从光源发出并经过多次反射形成的,它均匀从周围环境入射至物体表面并朝各个方向等量反射。漫反射光是直接从特定光源入射并朝各个方向等量反射的光,入射角越小它看起来越亮,同时从各个角度来看它的亮度是一样的。镜面光也是直接从特定光源入射的,但在反射时只朝特定的方向反射(遵从镜面反射定理)。一束平行激光在高质量的镜面上可以几乎被100%地反射。表面光泽的金属或塑料都有很高的镜面反射成份,而象粉笔或地毯之类的光泽度差的物品则几乎没有。尽管同一光源出射的光的频率分布是一定的,但照在不同的表面上产生的环境光、漫反射光、镜面光分量却可能不同。比如白光照在房间的红色墙壁上,被散射的光就会趋于红色。OpenGL允许对各个反射光分量的RGB值分别作独立的调整。§6.1.2材质颜色OpenGL中近似认为材质的颜色由它的反射光中的红绿蓝三色所占的百分比决定。比如:一个理想的红色球将反射入射的所有红光并吸收所有绿色和蓝色光。这样的球在白光(含红绿蓝三色光)和纯红光的照射下的表现是一致的--都是红色球,然而在不含红光成份的光(如纯绿光)的照射下则呈现为黑色(因为没有光被反射)。与光线对应,材质有独立的环境反射、漫反射和镜面反射颜色成份,分别决定了材质对环境光、漫反射光和镜面光的反射能力。环境反射和漫反射决定了物体的颜色,这两种成份很相象,甚至可以当作一种来处理。镜面反射色通常为白色或灰色,因此镜面反射的高光(highlights)通常是光源的镜面光成份的颜色和强度决定。想象一束白光照射在一个有光泽的红色金属球上,球体的大部分将表现为红色,而高光处则为白色。§6.1.3光线与材质的RGB值光线颜色的RGB值定义于材质的RGB值定义有所不同。对光线来说,RGB值的大小对应于该色光强度与其最高强度的比例百分数。比如一束光的RGB都是1.0,那么它就是最强的白光;如果这些值都为0.5,则整束光的颜色还是白色,只不过强度减半,看起来是灰色。如果R=G=1.0而B=0.0,那么就是最强的黄光。对材质来说,RGB值的大小对应于材质对该色光的反射比例百分数。比如某材质的R=1.0,G=0.5,B=0.0,则它反射入射的所有红光,一半的绿光,不反射蓝光。换句话来说,如果一束光的RGB值为(LR,LG,LB),被照材质的RG
本文标题:OpenGL点光源
链接地址:https://www.777doc.com/doc-7290546 .html