Computer Graphics Experiment III Part.1 LightModel in OpenGL (based on WalkingMan)

图形学实验三第一部分——实验二基础上的光照模型。 此次试验首先在上一个实验的基础上实现OpenGL自带的光照模型,比较不同的着色方法带来的不同,之后再通过GLSL写着色器实现两种不同的光照模型。 本篇博客首先在上一个实验:WalkMan 的基础上添加光照,并使用两种不同的着色方法。

光照模型

OpenGL中的光照模型中的反射光分为三个分量,分别是环境反射光(Ambient Light)、漫反射光(Diffuse Light)和镜面反射光(Specular Light)。

  • 环境光Ambient:是由光源发出经环境多次散射而无法确定其入射方向的光,即似乎来自所有方向。其特征是入射方向和出射方向均为任意方向。

  • 漫射光Diffuse:来自特定方向,它垂直于物体时比倾斜时更明亮。一旦它照射到物体上,则在各个方向上均匀地发散出去,效果为无论视点在哪里它都一样亮,其特征是入射方向唯一、出射方向为任意方向。

  • 镜面光Specular:来自特定方向并沿另一方向反射出去,一个平行激光束在高质量的镜面上产生100%的镜面反射,其特征是入射方向和出射方向均唯一。

创建光源

OpenGL中用函数glLightfv来创建光源,函数原型是:

1
void glLightfv (GLenum light, GLenum pname, const GLfloat *params)

第一个参数light指定所创建的光源号,如GL_LIGHT0、GL_LIGHT1、…、GL_LIGHT7。 第二个参数pname指定光源特性,这个参数的具体信息见下表所示。 第三个参数设置相应的光源特性值。 如下,我们便可以定义一个位置在(5,5,5)没有环境光,镜面反射光和漫反射光都为白光的光源

1
2
3
4
5
6
7
8
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 };
GLfloat light_position[] = { 5,5,5,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);

其中,position是其次坐标系,当第四个参数为0时,表示点光源,为1时表示由前三个数组成向量射来的平型光源。

Phong Model与Flat Model

我们用下列代码控制关照的模式

1
2
3
4
if (!smooth)
glShadeModel(GL_FLAT);
else
glShadeModel(GL_SMOOTH);

然后光照模型的对比如下: 可见,FLAT模式下出现了明显的马赫带。 新版本的OpenGL提供了更加自由的渲染模式,我们在下一篇博客中将利用其通过不同的Model渲染新的场景。