当前位置:文档之家› OpenGL光照和材质

OpenGL光照和材质


OpenGL 的光照和材质
glMaterialfv(GL_FRONT,GL_DIFFUSE,@Diffuse); 1 GL_FRONT(正面),GL_BACK(反面),GL_FRONT_AND_BACK(正反两面)。 2 GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR属性。这三个属性与光源的 三个对应属性类似,每一属性都由四个值组成。 GL_AMBIENT表示各种光线照射到该材质上,经过很多次反射后最终遗留在环境 中的光线强度(颜色)。 GL_DIFFUSE 表示光线照射到该材质上,经过漫反射后形成的光线强度(颜色)。 GL_SPECULAR表示光线照射到该材质上,经过镜面反射后形成的光线强度(颜 色)。 通常,GL_AMBIENT和GL_DIFFUSE都取相同的值,可以达到比较真实的效果。 使用GL_AMBIENT_AND_DIFFUSE可以同时设置GL_AMBIENT和GL_DIFFUSE 属性。
OpenGL 的光照和材质
2 创建聚光灯(这些属性只对位置性光源有效)
glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,LightCutOff); 表示将光源作为聚光灯使用。很多光源都是向四面八方发射光线,但有时候 一些光源则是只向某个方向发射,比如手电筒,只向一个较小的角度发射光 线。 GL_SPOT_DIRECTION 属性有三个值,表示一个向量,即光源发射的方向。 光源的默认方向是(0.0,0.0,-1.0),即指向z轴负方向 GL_SPOT_EXPONENT 属性只有一个值,表示聚光的程度,为零时表示光 照范围内向各方向发射的光线强度相同,为正数时表示光照向中央集中,正 对发射方向的位置受到更多光照,其它位置受到较少光照。数值越大,聚光 效果就越明显。 GL_SPOT_CUTOFF 属性也只有一个值,表示一个角度,它是光源发射光线 所覆盖角度的一半,其取值范围在0到90之间,也可以取180这个特殊值。取 值为180时表示光源发射光线覆盖360度,即不使用聚光灯,向全周围发射。 即一个点光源。
OpenGL 的光照和材质
6 使用颜色跟踪(这将导致正面的DIFFUSE总是设置为当前颜色) 在启用光照系统之后,为图元指定颜色变得不太方便。首先我们需要创建一 个数组,然后调用glMaterial函数将数组传给材质,以此决定物体的颜色。为 了简便,我们可以开启颜色跟踪来简化代码。调用 glEnable(GL_CORLOR_MATERIAL); 启动颜色跟踪,再调用 glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); 来决定对物体的正面还是反面,对环境光、镜面光还是漫射光进行颜色跟踪。 第一个参数可以取 GL_FRONT、GL_BACK、GL_FRONT_AND_BACK中的任意一种, 第二个参数可以取 GL_AMBIENT、GL_DIFFUSE、GL_AMBIENT_AND_DIFFUSE、 GL_SPECULAR中的任意一种。 启动颜色跟踪之后,我们就可以像以前一样,使用glColor函数来指定图元的 颜色了。这时,OpenGL将自动根据从glColor函数传递的颜色来决定物体材 质,
OpenGL 的光照和材质
4 为图元指定法向量:
OpenGL必须通过图元的法线向量来确定图元的明暗程度 通过计算得到法线向量后,我们需要在绘制顶点前调用glNormal函数为顶点 或图元指定法线 使用glTranslate*函数或者glRotate*函数可以改变物体的外观,但法线向量并 不会随之改变。然而,使用glScale*函数,对每一坐标轴进行不同程度的缩放, 很有可能导致法线向量的不正确,虽然OpenGL提供了一些措施来修正这一问 题,但由此也带来了各种开销。因此,在使用了法线向量的场合,应尽量避 免使用glScale*函数。即使使用,也最好保证各坐标轴进行等比例缩放 对光源进行平移或旋转,使之相对于静止的物体移动,这可以在指定模型变 换后设置光源位置,然后通过修改模型变换来改变光源的位置。
OpenGL 的光照和材质
5 设置材质: OpenGL 用材料对光的红、绿、蓝三原色的反射率来近似定义材料的颜色。象光 源一样,材料颜色也分成环境、漫反射和镜面反射成分,它们决定了材料对环境 光、漫反射光和镜面反射光的反射程度。在进行光照计算时,材料对环境光的反 射率与每个进入光源的环境光结合,对漫反射光的反射率与每个进入光源的漫反 射光结合,对镜面光的反射率与每个进入光源的镜面反射光结合。对环境光与漫 反射光的反射程度决定了材料的颜色,并且它们很相似。对镜面反射光的反射率 通常是白色或灰色(即对镜面反射光中红、绿、蓝的反射率相同)。镜面反射高 光最亮的地方将变成具有光源镜面光强度的颜色。例如一个光亮的红色塑料球, 球的大部分表现为红色,光亮的高光将是白色的材质的颜色与光源的颜色有些不 同。对于光源,R、G、B 值等于R、G、B 对其最大强度的百分比。若光源颜色 的R、G、B 值都是1.0,则是最强的白光;若值变为0.5,颜色仍为白色,但强度 为原来的一半,于是表现为灰色;若R=G=1.0,B=0.0,则光源为黄色。对于 材质,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)指定了图元的法线之后,我们还需要为 其指定相应的材质以决定物体对各种颜色的光的反射程度,这将影响物体表现为 何种颜色指定材质
OpenGL 的光照和材质
3 设置光线衰减系数(这些属性只对位置性光源有效)
glLightf(GL_LIGHT0,AttenuationWay,SpotAttenuation); AttenuationWay可以取以下几个值: GL_CONSTANT_ATTENUATION -- 表示光线按常熟衰减(与距离无关) GL_LINEAR_ATTENUATION -- 表示光线按距离线性衰减 GL_QUADRATIC_ATTENUATION -- 表示光线按距离以二次函数衰减。 参数 SpotAttenuation为光线的衰减系数。 GL_CONSTANT_ATTENUATION、GL_LINEAR_ATTENUATION、 GL_QUADRATIC_ATTENUATION属性。这三个属性表示了光源所发出的光 线的直线传播特性。现实生活中,光线的强度随着距离的增加而减弱, OpenGL把这个减弱的趋势抽象成函数: 衰减因子 = 1 / (k1 + k2 * d + k3 * k3 * d) 其中d表示距离,光线的初始强度乘以衰减因子,就得到对应距离的光线强度。 k1, k2, k3分别是 GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADR ATIC_ATTENUATION。通过设置这三个常数,就可以控制光线在传播过程中 的减弱趋势。
OpenGL 的光照和材质
GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR这三种属性是光源和材质所 共有的,如果某光源发出的光线照射到某材质的表面,则最终的漫反射强度 由 两 个 GL_DIFFUSE 属 性 共 同 决 定 , 最 终 的 镜 面 反 射 强 度 由 两 个 GL_SPECULAR属性共同决定。 在OpenGL中,仅仅支持有限数量的光源。使用GL_LIGHT0表示第0号光 源, GL_LIGHT1 表示第 1 号光源,依次类推, OpenGL 至少会支持 8 个光源, 即 GL_LIGHT0 到 GL_LIGHT7 。 使 用 glEnable 函 数 可 以 开 启 它 们 。 例 如 , glEnable(GL_LIGHT0) 可以开启第 0 号光源。使用 glDisable 函数则可以关闭光 源。一些OpenGL实现可能支持更多数量的光源,但总的来说,开启过多的 光源将会导致程序运行速度的严重下降, 光源GL_LIGHT0与其他几个光源不同, GL_DIFFUSE,GL_SPECULAR的默认值是(1.0,1.0,1.0,1.0) 而其他光源的默认值是 (0.0,0.0,0.0,1.0)。
OpenGL 的光照和材质
使用OpenGL的光照模型包括以下几个步骤: 1 设置光源的种类、位置和方向(对于平行光源) 2 为每个图元的每个顶点指定它的法线向量 3 为各个图元指定它的材质 4 启用光照模型
OpenGL 的光照和材质
1 光源设置: 设置环境光:glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight); 设置漫射光成分:glLightfv(GL_LIGHT0,GL_DIFFUSE,DiffuseLight) 设置镜面光成分:glLightfv(GL_LIGHT0,GL_SPECULAR,SpecularLight); 光源的属性GL_SPECULAR影响镜面反射区域的颜色,一般物体的镜面反射 区域的颜色为入射光线的颜色,要实现真实感,应该将它的值设置成与 GL_DIFFUSE相同。 设置光源的位置:glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position); GL_POSITION属性,表示光源所在的位置。由四个值(X, Y, Z, W)表示。 方向性光源 第四个值W为零,则表示该光源位于无限远处,前三个值表示了 它所在的方向。通常,太阳可以近似的被认为是方向性光源。 位置性光源 第四个值W不为零,则X/W, Y/W, Z/W表示了光源的位置。这种光 源称为位置性光源。 定位光源需要对其发射的光进行衰减,可以设置各种衰减因子。环境光,散 射光和镜面反射光的贡献都是衰减的,只有发射光和全局环境光不会衰减。
Ope在(1,1,1),没有环境光,镜面反射光和漫反射光都为白 光的光源: GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat light_ambient [] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat light_diffuse [] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightfv(GL_LIGHT0, GL_AMBIENT , light_ambient ); glLightfv(GL_LIGHT0, GL_DIFFUSE , light_diffuse ); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
相关主题