计算机图形学——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*函数具有三个参数,第一个参数指明是设置哪一个光源的属性,第二个参数指明是设置该光源的哪一个属性,第三个参数则是指明把该属性值设置成多少。光源的属性:

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

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

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

  2. 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*函数可以指定的材质属性。

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

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

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

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

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


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

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

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

4、光照模型

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

  1. 全局环境光线:那些充分散射,无法分清究竟来自哪个光源的光线的强度
  2. 观察点位置是在较近位置还是在无限远处
  3. 物体正面与背面是否分别计算光照
  4. 镜面颜色(即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、实例演示:


计算机图形学——OpenGL之光照_第1张图片

源码:
#include 

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();
	
}


你可能感兴趣的:(计算机图形学)