光照材质.docx

上传人:hw****26 文档编号:3083698 上传时间:2019-05-20 格式:DOCX 页数:8 大小:25.59KB
下载 相关 举报
光照材质.docx_第1页
第1页 / 共8页
光照材质.docx_第2页
第2页 / 共8页
光照材质.docx_第3页
第3页 / 共8页
光照材质.docx_第4页
第4页 / 共8页
光照材质.docx_第5页
第5页 / 共8页
点击查看更多>>
资源描述

1、opengl 学习笔记之光照、材质OpenGL 在处理光照时把光照系统分为三部分,分别是光源、材质和光照模型。光源、材质和光照模式都有各自的属性,尽管属性种类繁多,但这些属性都只用很少的几个函数来设置。使用 glLight*函数可设置光源的属性,使用 glMaterial*函数可设置材质的属性,使用 glLightModel*函数可设置光照模式。GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR 这三种属性是光源和材质所共有的,如果某光源发出的光线照射到某材质的表面,则最终的漫反射强度由两个 GL_DIFFUSE 属性共同决定,最终的镜面反射强度由两个 GL_SPECULAR

2、属性共同决定。在 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 的默

3、认值是(1.0,1.0,1.0,1.0)而其他光源的默认值是 (0.0,0.0,0.0,1.0)。使用 OpenGL 的光照模型包括以下几个步骤:1 设置光源的种类、位置和方向(对于平行光源)2 为每个图元的每个顶点指定它的法线向量3 为各个图元指定它的材质4 启用光照模型1 光源设置设置环境光glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);设置漫射光成分glLightfv(GL_LIGHT0,GL_DIFFUSE,DiffuseLight)设置镜面光成分glLightfv(GL_LIGHT0,GL_SPECULAR,SpecularLight);光源

4、的属性 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 表示了光源的位置。这种光源称为位

5、置性光源。定位光源需要对其发射的光进行衰减,可以设置各种衰减因子。环境光,散射光和镜面反射光的贡献都是衰减的,只有发射光和全局环境光不会衰减。对于,设置其位置与设置多边形顶点的方式相似,各种矩阵变换函数例如:glTranslate*、glRotate*等在这里也同样有效。方向性光源在计算时比位置性光源快了不少,因此,在视觉效果允许的情况下,应该尽可能的使用 方向性 光源。下面定义了一个位置在(1,1,1),没有环境光,镜面反射光和漫反射光都为白光的光源GLfloat light_position = 1.0, 1.0, 1.0, 0.0 ;GLfloat light_ambient = 0.0

6、, 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_spec

7、ular);2 创建聚光灯(这些属性只对位置性光源有效)glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,LightCutOff);GL_SPOT_DIRECTION、GL_SPOT_EXPONENT、GL_SPOT_CUTOFF 属性。表示将光源作为聚光灯使用。很多光源都是向四面八方发射光线,但有时候一些光源则是只向某个方向发射,比如手电筒,只向一个较小的角度发射光线。GL_SPOT_DIRECTION 属性有三个值,表示一个向量,即光源发射的方向。光源的默认方向是(0.0,0.0,-1.0),即指向 z 轴负方向GL_SPOT_EXPONENT 属性只有一个值,表示聚光的

8、程度,为零时表示光照范围内向各方向发射的光线强度相同,为正数时表示光照向中央集中,正对发射方向的位置受到更多光照,其它位置受到较少光照。数值越大,聚光效果就越明显。GL_SPOT_CUTOFF 属性也只有一个值,表示一个角度,它是光源发射光线所覆盖角度的一半,其取值范围在 0 到 90 之间,也可以取 180 这个特殊值。取值为 180 时表示光源发射光线覆盖 360 度,即不使用聚光灯,向全周围发射。即一个点光源。3 设置光线衰减系数(这些属性只对位置性光源有效)glLightf(GL_LIGHT0,AttenuationWay,SpotAttenuation);AttenuationWay

9、 可以取以下几个值:GL_CONSTANT_ATTENUATION - 表示光线按常熟衰减(与距离无关)GL_LINEAR_ATTENUATION - 表示光线按距离线性衰减GL_QUADRATIC_ATTENUATION - 表示光线按距离以二次函数衰减。参数 SpotAttenuation 为光线的衰减系数。GL_CONSTANT_ATTENUATION、GL_LINEAR_ATTENUATION、GL_QUADRATIC_ATTENUATION 属性。这三个属性表示了光源所发出的光线的直线传播特性。现实生活中,光线的强度随着距离的增加而减弱,OpenGL 把这个减弱的趋势抽象成函数:衰减

10、因子 = 1 / (k1 + k2 * d + k3 * k3 * d)其中 d 表示距离,光线的初始强度乘以衰减因子,就得到对应距离的光线强度。k1, k2, k3 分别是GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION。通过设置这三个常数,就可以控制光线在传播过程中的减弱趋势。4 为图元指定法向量OpenGL 必须通过图元的法线向量来确定图元的明暗程度通过计算得到法线向量后,我们需要在绘制顶点前调用 glNormal 函数为顶点或图元指定法使用 glTranslate*函数或者 glRotate*函

11、数可以改变物体的外观,但法线向量并不会随之改变。然而,使用 glScale*函数,对每一坐标轴进行不同程度的缩放,很有可能导致法线向量的不正确,虽然 OpenGL 提供了一些措施来修正这一问题,但由此也带来了各种开销。因此,在使用了法线向量的场合,应尽量避免使用 glScale*函数。即使使用,也最好保证各坐标轴进行等比例缩放对光源进行平移或旋转,使之相对于静止的物体移动,这可以在指定模型变换后设置光源位置,然后通过修改模型变换来改变光源的位置。5 设置材质OpenGL 用材料对光的红、绿、蓝三原色的反射率来近似定义材料的颜色。象光源一样,材料颜色也分成环境、漫反射和镜面反射成分,它们决定了材

12、料对环境光、漫反射光和镜面反射光的反射程度。在进行光照计算时,材料对环境光的反射率与每个进入光源的环境光结合,对漫反射光的反射率与每个进入光源的漫反射光结合,对镜面光的反射率与每个进入光源的镜面反射光结合。对环境光与漫反射光的反射程度决定了材料的颜色,并且它们很相似。对镜面反射光的反射率通常是白色或灰色(即对镜面反射光中红、绿、蓝的反射率相同)。镜面反射高光最亮的地方将变成具有光源镜面光强度的颜色。例如一个光亮的红色塑料球,球的大部分表现为红色,光亮的高光将是白色的。材质的颜色与光源的颜色有些不同。对于光源,R、G、B 值等于 R、G、B 对其最大强度的百分比。若光源颜色的 R、G、B 值都是

13、 1.0,则是最强的白光;若值变为 0.5,颜色仍为白色,但强度为原来的一半,于是表现为灰色;若 RG1.0,B0.0,则光源为黄色。对于材质,R、G、B 值为材质对光的 R、G、B 成分的反射率。比如,一种材质的 R1.0、G0.5、B0.0,则材质反射全部的红色成分,一半的绿色成分,不反射蓝色成分。也就是说,若 OpenGL 的光源颜色为(LR、LG、LB),材质颜色为(MR、MG、MB),那么,在忽略所有其他反射效果的情况下,最终到达眼睛的光的颜色为(LR*MR、LG*MG、LB*MB)指定了图元的法线之后,我们还需要为其指定相应的材质以决定物体对各种颜色的光的反射程度,这将影响物体表现

14、为何种颜色指定材质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 表示光线照射到该材质上,经过镜面反射后形成的光线强

15、度(颜色)。通常,GL_AMBIENT 和 GL_DIFFUSE 都取相同的值,可以达到比较真实的效果。使用GL_AMBIENT_AND_DIFFUSE 可以同时设置 GL_AMBIENT 和 GL_DIFFUSE 属性。3 GL_SHININESS 属性。该属性只有一个值,称为“镜面指数”,取值范围是 0 到 128。该值越小,表示材质越粗糙,点光源发射的光线照射到上面,也可以产生较大的亮点。该值越大,表示材质越类似于镜面,光源照射到上面后,产生较小的亮点。4 GL_EMISSION 属性。该属性由四个值组成,表示一种颜色。OpenGL 认为该材质本身就微微的向外发射光线,以至于眼睛感觉到它

16、有这样的颜色,但这光线又比较微弱,以至于不会影响到其它物体的颜色。5 GL_COLOR_INDEXES 属性。该属性仅在颜色索引模式下使用,由于颜色索引模式下的光照比 RGBA 模式要复杂,并且使用范围较小,这里不做讨论。 它们的数值情况如下:GLfloat earth_mat_ambient = 0.0f, 0.0f, 0.5f, 1.0f;GLfloat earth_mat_diffuse = 0.0f, 0.0f, 0.5f, 1.0f;GLfloat earth_mat_specular = 0.0f, 0.0f, 1.0f, 1.0f;GLfloat earth_mat_emissi

17、on = 0.0f, 0.0f, 0.0f, 1.0f;GLfloat earth_mat_shininess = 30.0f;(0-128)6 使用颜色跟踪 (这将导致正面的 DIFFUSE 总是设置为当前颜色)?在启用光照系统之后,为图元指定颜色变得不太方便。首先我们需要创建一个数组,然后调用 glMaterial 函数将数组传给材质,以此决定物体的颜色。为了简便,我们可以开启颜色跟踪来简化代码。调用glEnable(GL_CORLOR_MATERIAL);启动颜色跟踪,再调用glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);来决定对物体的正

18、面还是反面,对环境光、镜面光还是漫射光进行颜色跟踪。第一个参数可以取GL_FRONT、GL_BACK、GL_FRONT_AND_BACK 中的任意一种,第二个参数可以取GL_AMBIENT、GL_DIFFUSE、GL_AMBIENT_AND_DIFFUSE、GL_SPECULAR 中的任意一种。启动颜色跟踪之后,我们就可以像以前一样,使用 glColor 函数来指定图元的颜色了。这时,OpenGL 将自动根据从 glColor 函数传递的颜色来决定物体材质,画了一个红色的有立体感的球glPushMatrix();glEnable(GL_COLOR_MATERIAL);glColorMateri

19、al(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);glColor3f(1.0,0.0,0.0);glutSolidSphere(1.0, 16, 16);glDisable(GL_COLOR_MATERIAL);glPopMatrix();7 光照模型光照模型有 4 部分:全局环境光 近视点或远视点双面光照 镜面反射颜色是否和环境颜色,散射颜色分开。指定全局环境光GLfloat ambient=0.3,0.3,0.3,1.0;glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient);顶点的镜面反射亮度取决于该点的法线,顶点相对于光源的方

20、向以及顶点相对于视点的方向。使用近视点,glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE);这就将视点放置在(0,0,0)处.启用双面光照glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE)。镜面反射颜色和环境颜色,散射颜色分开典型的光照计算中,分别计算环境光,散射光,镜面反射光和发射光的贡献,然后进行叠加,而在这之后进行纹理映射的话,镜面反射区可能被覆盖,为了解决这个问题,可以 glLightModelfv(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECU

21、LAR_COLOR);这样,每个顶点光照计算将产生两种颜色,主颜色和辅助颜色,前者包含所有非镜面反射光照的贡献,后者是所有镜面反射光照的总贡献。纹理映射的时候只将主颜色和纹理颜色混合起来,执行完纹理映射后,再将主颜色和纹理颜色的混合结果与辅助颜色混合起来。4 为图元指定法向量OpenGL 必须通过图元的法线向量来确定图元的明暗程度。只有场景中的物体有了明暗的不同,场景才有立体感。确定一个平面的法向量是一件相当简单的事情。在一个平面上,随意寻找两个互不平行的向量,它们的外积(叉积)就是这个平面的法线。计算两向量的外积可以使用公式:Sx = UyVz - UzVySy = UzVx - UxVzS

22、z = UxVy - UyVx上述公式中,U、V 为两不平行向量, S 为 U、V 的外积 (即 UV)。计算完外积之后,我们还需要将得到的向量转换为单位向量。只要将一个向量的x、y、z 因子全部除以该向量的模就可以得到单位向量。因此,可以使用下面的代码计算一个三角形的法线向量。请注意应该将三角形的顶点按逆时针顺序传给函数以获得正确结果。通过计算得到法线向量之后,我们需要在绘制顶点之前调用 glNormal 函数为顶点或图元指定法线。例如:glBegin(GL_TRIANGLES);glNormal3f(1,1,1); /为即将绘制的三角形指定法线glVertex3f(1,0,1);glVer

23、tex3f(1,1,1);glVertex3f(1,0,0);glEnd();除此之外,也可以为同一图元的不同顶点指定不同法线向量。例如:glBegin(GL_TRIANGLES);glNormal3f(1,1,1);glVertex3f(1,0,1);glNormal3f(1,0,1);glVertex3f(1,1,1);glNormal3f(0,1,1);glVertex3f(1,0,0);glEnd(); 5 材质指定了图元的法线之后,我们还需要为其指定相应的材质以决定物体对各种颜色的光的反射程度,这将影响物体表现为何种颜色。和光源的成分相似,材质也分为漫射光反光率、平行光反光率。材质的

24、漫射光成分将决定该材质对环境中的漫射光的反射程度,相似的,平行光成分将决定材质对平行光的反射程度。与设置光源相似,我们只需在绘制图元之前调用 glMaterialf 或 glMaterialfv 函数就能对即将绘制的图元的材质的各项参数进行设定。5.1 设置材质对各种光的反光率调用:glMaterialfv(GL_FRONT,GL_DIFFUSE,Diffuse);可以指定材质对漫射光的反射率。其中,第一个参数决定该材质运用于图元的正面还是反面。可以取 GL_FRONT(正面),GL_BACK( 反面),GL_FRONT_AND_BACK(正反两面)。第 2 个值表示对何种光进行设置,GL_D

25、IFFUSE 表示对漫射光反射率进行设置,可以取 GL_AMBIENT(环境光)、GL_DIFFUSE(漫射光)、GL_AMBIENT_AND_DIFFUSE(环境光和漫射光) 、GL_SPECULAR( 平行/镜面光)。而第三个参数是一个四维数组,这个数组描述了反光率的 RGBA 值,每一项取值都为 0-1 之间。例如Diffuse4=1,0,0,1;glMaterialfv(GL_FRONT,GL_DIFFUSE,Diffuse);将会使物体在有红色成分的光照下表现为红色。5.2 使用颜色跟踪在启用光照系统之后,为图元指定颜色变得不太方便。首先我们需要创建一个数组,然后调用 glMater

26、ial 函数将数组传给材质,以此决定物体的颜色。为了简便,我们可以开启颜色跟踪来简化代码。调用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 中的任意一种。启动颜色跟踪之后

27、,我们就可以像以前一样,使用 glColor 函数来指定图元的颜色了。这时,OpenGL 将自动根据从 glColor 函数传递的颜色来决定物体材质,省去了我们手工指定材质的麻烦。 例如,要在启用光照系统的前提下绘制一个红色的三角形,可以这样做:glEnable(GL_COLOR_MATERIAL);glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);glColor3ub(255,0,0);glBegin(GL_TRIANGLES);glVertex3f(1,0,1);glVertex3f(1,1,1);glVertex3f(1,0,0);glEn

28、d();5.3 材质的镜面指数当光源中含有镜面光成分,且镜面光较强时,一些光滑的物体便会出现一些高亮的焦点我们可以通过设置材质的镜面指数来确定光斑的大小和聚焦程度。调用glMateriali(GL_FRONT,GL_SHININESS,N );可以对镜面指数进行设定。如果 N 值越大,则光斑尺寸越小,物体越有光泽,反之越大。N 值可取 1-128 之间的任意整数。5.4 辐射性材质有些物体,本身会发光。我们可以设置材质的 Emission 成分来使物体看起来有发光效果。只需添加如下代码:int LightEmission4=1,1,0,1glMaterialfv(GL_FRONT,GL_EMISSION,LightEmission);其中,LightEmission 表示物体所发光的颜色的 RGBA 值。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育教学资料库 > 精品笔记

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。