Advertisement

计算机图形学——OpenGL之光照

阅读量:

计算机图形学——OpenGL之光照

1、光照系统

光照系统可以分为三部分:

  • 光源就是光的来源,可以是太阳或者电灯等。

材质是指接受光照的各种物体的表面,由于物体如何反射光线只由物体表面决定(OpenGL中没有考虑光的折射),材质特点就决定了物体反射光线的特点。

光照环境是指一些额外的参数,它们将影响最终的光照画面,比如一些光线经过多次反射后,已经无法分清它究竟是由哪个光源发出,这时,指定一个“环境亮度”参数,可以使最后形成的画面更接近于真实情况。

相关概念:

  • 镜面反射:光线入射理想的光滑平面,反射后的光线是很规则的

  • 漫反射:光线入射粗糙的、不光滑的平面,反射后的光线是杂乱的

2、设置光源

在OpenGL中,仅仅支持有限数量的光源。使用GL_LIGHT0表示第0号光源,GL_LIGHT1表示第1号光源,依次类推。OpenGL至多会支持8个光源,即GL_LIGHT0到GL_LIGHT7。使用glEnable函数可以开启它们。例如,glEnable(GL_LIGHT0);可以开启第0号光源。使用glDisable函数则可以关闭光源。

每一个光源都可以设置其属性,这一动作是通过glLight函数完成的。glLight函数具有三个参数,第一个参数指明是设置哪一个光源的属性,第二个参数指明是设置该光源的哪一个属性,第三个参数则是指明把该属性值设置成多少。光源的属性:

GL_AMBIENT表示该光源所发出的光,经过非常多次的反射后,最终遗留在整个光照环境中的强度

GL_DIFFUSE表示该光源所发出的光,照射到粗糙表面时经过漫反射,所得到的光的强度

GL_SPECULAR表示该光源所发出的光,照射到光滑表面时经过镜面反射,所得到的光的强度。 其中每个属性由四个值表示,分别代表了颜色的R, G, B, A值。

GL_POSITION属性。表示光源所在的位置。由四个值(X, Y, Z, W)表示。如果第四个值W为零,则表示该光源位于无限远处,前三个值表示了它所在的方向。这种光源称为方向性光源,通常,太阳可以近似的被认为是方向性光源。

如果第四个值W不为零,则X/W, Y/W, Z/W表示了光源的位置。这种光源称为位置性光源。对于位置性光源,设置其位置与设置多边形顶点的方式相似,各种矩阵变换函数例如:glTranslate*、glRotate*等在这里也同样有效。

方向性光源在计算时比位置性光源快了不少,因此,在视觉效果允许的情况下,应该尽可能的使用方向性光源。

GL_SPOT_DIRECTION、GL_SPOT_EXPONENT、GL_SPOT_CUTOFF属性。表示将光源作为聚光灯使用(这些属性只对位置性光源有效)。

GL_CONSTANT_ATTENUATION、GL_LINEAR_ATTENUATION、GL_QUADRATIC_ATTENUATION属性。这三个属性表示了光源所发出的光线的直线传播特性(这些属性只对位置性光源有效)

3、设置材质

光源是通过glLight函数来设置的,而材质则是通过glMaterial函数来设置的。glMaterial*函数有三个参数。第一个参数表示指定哪一面的属性。可以是GL_FRONT、GL_BACK或者GL_FRONT_AND_BACK。分别表示设置“正面”“背面”的材质,或者两面同时设置。

下面分别说明glMaterial*函数可以指定的材质属性。

GL_AMBIENT表示各种光线照射到该材质上,经过很多次反射后最终遗留在环境中的光线强度。

GL_DIFFUSE表示光线照射到该材质上,经过漫反射后形成的光线强度。

GL_SPECULAR表示光线照射到该材质上,经过镜面反射后形成的光线强度。

通常,GL_AMBIENT和GL_DIFFUSE都取相同的值,可以达到比较真实的效果。

使用GL_AMBIENT_AND_DIFFUSE可以同时设置GL_AMBIENT和GL_DIFFUSE属性。

GL_SHININESS属性。该属性只有一个值,称为“镜面指数”,取值范围是0到128。

该值越小,表示材质越粗糙,点光源发射的光线照射到上面,也可以产生较大的亮点。该值越大,表示材质越类似于镜面,光源照射到上面后,产生较小的亮点。

GL_EMISSION属性。该属性由四个值组成,表示一种颜色。OpenGL认为该材质本身就微微的向外发射光线,以至于眼睛感觉到它有这样的颜色,但这光线又比较微弱,以至于不会影响到其它物体的颜色。

4、光照模型

在OpenGL中,光照模型包括四个部分的内容:

  1. 全局环境光线:那些充分散射,无法分清究竟来自哪个光源的光线的强度
  1. 观察点位置是在较近位置还是在无限远处
  1. 物体正面与背面是否分别计算光照
  1. 镜面颜色(即GL_SPECULAR属性所指定的颜色)的计算是否从其它光照计算中分离出来,并在纹理操作以后在进行应用

可以通过函数glLightModel*来进行设置。该函数有两个参数,第一个表示要设置的项目,第二个参数表示要设置成的值。

GL_LIGHT_MODEL_AMBIENT表示全局环境光线强度,由四个值组成。

GL_LIGHT_MODEL_LOCAL_VIEWER表示是否在近处观看,若是则设置为GL_TRUE,否则(即在无限远处观看)设置为GL_FALSE。

GL_LIGHT_MODEL_COLOR_CONTROL表示颜色计算方式。

GL_LIGHT_MODEL_TWO_SIDE表示是否执行双面光照计算。如果设置为GL_TRUE,则OpenGL不仅将根据法线向量计算正面的光照,也会将法线向量反转并计算背面的光照。

OpenGL默认是关闭光照处理的。要打开光照处理功能,使用下面的语句:

glEnable(GL_LIGHTING);

同样要关闭光照处理功能,使用glDisable(GL_LIGHTING)。

5、实例演示:

源码:

复制代码
 #include <GL/glut.h>

    
  
    
 void GL_display();
    
 void GL_reshape(GLsizei w, GLsizei h);
    
 void GL_myInitial();
    
  
    
 void main(void)
    
 {
    
 	glutCreateWindow("Gouraud光照模型");
    
 	GL_myInitial();
    
 	glutDisplayFunc(GL_display);
    
 	glutReshapeFunc(GL_reshape);
    
 	glutMainLoop();
    
 }
    
  
    
 void GL_myInitial()
    
 {
    
 	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);
    
  
    
  
    
 	glEnable(GL_LIGHTING);
    
 	glEnable(GL_LIGHT0);
    
 	glDepthFunc(GL_LESS);
    
 	glEnable(GL_DEPTH_TEST);
    
 }
    
  
    
 void GL_display()
    
 {
    
 	
    
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
 	glutSolidTeapot(0.5);
    
 	glFlush();
    
  
    
 }
    
  
    
 void GL_reshape(GLsizei w, GLsizei h)
    
 {
    
 		
    
 	glViewport(0, 0, w, h);
    
 	
    
 	glMatrixMode(GL_PROJECTION);
    
 	glLoadIdentity();
    
 	if (w <= h)
    
     glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
    
 	else
    
     glOrtho (-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
    
  
    
 	glMatrixMode(GL_MODELVIEW);
    
 	glLoadIdentity();
    
 	
    
 }
    
    
    
    
    AI生成项目cpp
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-12/VGlHAfdhyob5nEDuLNj1W7SMYmrc.png)

全部评论 (0)

还没有任何评论哟~