以前总是避开光照着部分不看,虽然可以写程序,但是有一点总是不明白,所以那次数据结构课程设计
的光照虽然用了,但效果很烂。
今天重看了一遍,完全是为了彻底搞明白这个小问题。
OpenGL光照分4种以模拟真实的世界:环境光,散射光,反射光,放射光。
在OpenGL里常需要设置光照的属性( 函数glLight*() ),还要设置物体的材质( 函数glMaterial() ),
我不明白的地方就是,既然设置了光照的属性,比如光照的颜色,然后比方说场景中有一个绿色的球体,
那么我们先定义这个绿色球体,然后,设置一个红色灯光,于是灯管就照射到绿色球体。
在真实世界确实是这样。可是,在OpenGL里面,我们还要调用glMaterial()函数来设置他的反射光和满射光
的颜色,我以为这是完全没必要的。因为真实世界是不必要的。
现在明白我忽略了一件事情,就是绿色场景中的物体并不是说可以自动反射某种颜色的,就是说,
他的颜色不是说可以设置的,因此它反射的光的颜色还必须指定。
比如这样代码:
void display( )
{
glClearColor( 0.0, 0.0, 0.0, 0.0 );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; //白色
GLfloat mat_shininess[] = { 50.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; //白色
GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 }; //白色
GLfloat lmode_ambient[] = { 0.1, 1.0, 0.1, 1.0 }; //白色
glShadeModel( GL_SMOOTH );
glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular );
glMaterialfv( GL_FRONT, GL_SHININESS, mat_shininess );
glLightfv( GL_LIGHT0, GL_POSITION, light_position );
glLightfv( GL_LIGHT0, GL_DIFFUSE, white_light );
glLightfv( GL_LIGHT0, GL_SPECULAR, white_light );
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable( GL_DEPTH_TEST );
glutSolidSphere(0.5, 20, 16);
glFlush ();
}
用glutSolidSphere(0.5, 20, 16);生成的这个球体的颜色你是不能指定的,然后他到底反射什么光呢?
这个当然得程序员自己定义。
如果你将glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 );这两句注释掉你就发现场景中的球体实际上
很白很白的。
白色物体当然会反射所有的光。
当然如果是白的光源,当然它会反射白色的光,但是我们却可以让他反射红色光,程序员是上帝。。。
代码修改如下:(注意到我们的光源还是白色的)
GLfloat mat_diffuse[] = { 1.0, 0.0, 0.0, 1.0 };
glMaterial( GL_FRONT, GL_DIFFUSE, mat_diffuse );
然后再运行应该就可以看到球体反射红色光线。
因为,如果光照颜色为(LR, LG, LB),材料的颜色为(MR, MG, MB),那么进入人眼的最终光线为:
( LR*MR, LG*MG, LB* MB )