3.2 光照篇(1)

http://book.51cto.com/art/201104/255654.htm

3.2   光照篇(1)

大家之所以能够看到东西,主要是因为物体上有光进入大家的眼睛,无论这个光的来源如何。假若,一个物体自身并不发光而且不反射任何光线,那么把它放到最强的阳光下你也看不到什么。因此,OpenGL中既要设置光线性质,又要设置物体的反射性质(告诉OpenGL,光线如何进入我们的眼睛)。

1.光线的分类及设置

OpenGL中的光主要有以下4种:自发光、环境光(ambient)、散射光(diffuse)、镜面反射光(specular)。不同的书翻译方法不太一样,有些书将自发光单独归类。还有些书将它们分别翻译成发射光线、环境光线、散射光线、镜面反射光线。还有一些书将镜面反射光翻译为镜面光或者是反射光,我个人认为是不太完整的。我们这里的翻译主要是为了同初中物理中的光学知识相衔接。

一起来复习一下初中物理中有关光的知识。光线归根结底都是由光源"发出"的,光源到物体之间的光线初中物理中称为"入射光线"(它并没有到达我们的眼睛),而物体"处理"后的光线在初中物理中有两种"反射光线与折射光线"--它们中的一小部分到达我们的眼睛。

自发光:物体本身发出的光线(大多数物体是没有自发光的,仅太阳、电灯、蜡烛等物体有自发光)。

环境光:以完全相同的强度从空间的任何一个方向照射到物体上,物体对环境光的反射在任何方向上是等量的。通俗来讲就是,来的时候没有方向,去的时候也没有方向。所以,在只有环境光的照射情况下,我们从任何角度观察物体,其亮度是一样的。我们认为它只起一个照亮的作用,对增加3D效果作用不大。生活中能产生环境光的光源是不存在的,医学的无影灯勉强算是。

事实上,OpenGL中认为环境光是各种光线的综合产物。如屋子里桌面上放置的一个正方体,它所接受的光线包括:太阳光照向墙壁产生的光线、太阳光照向桌子产生的光线、太阳光照向空气中的微尘颗粒产生的光线、太阳光透过玻璃产生的光线、电灯的直接照射、电灯照在不同物体上折射产生的光线等。虽然生活中找不到环境光源的实例,但OpenGL中假设存在这样的光源,称为"环境光源"。

散射光:从固定方向照向物体,但物体对它反射在任何方向是均匀的。当然,它直接照到的部分比较亮,扫过的部分相对较暗。通俗来讲就是,来的时候固定方向,去的时候没有方向。

镜面反射光:来源于特定方向的光源并向特定方向反射的光线。通俗来讲就是,来的时候固定方向,去的时候也固定方向。

启用光照:glEnable(GL_LIGHTING)。对于任何光照效果这个命令是必需的,相当于启用光照的大门。如果启用光照后,不添加任何别的光照代码,那么你看到的物体为黑色的,并且glColor所设置的颜色也起不了作用。

设置光照模式(glLightModel):有些书把它翻译成光照模型,是不太贴切的。GlLightModelfv(GL_LIGHT_MODEL_AMBIENT,V):用于设置环境光,其中要求V为四元向量。且其所有的分量取值范围为[0,1],分别表示红、绿、蓝及透明度的强度。其默认值为(0,0,0,1)。这里我不得不承认自己曾经被这个命令误导过,我本来认为把"GL_LIGHT_MODEL_AMBIENT"替换成"GL_LIGHT_MODEL_DIFFUSE"可以用来设置散射光,换成"GL_LIGHT_MODEL_SPECULAR"可以用来设置镜面反射光,但事实并非如此。查阅一些资料后发现,这两类光的设置要放在光源的内容中。事实上这个命令所启用的环境光,最贴切的名称应该是全局环境光,用于设置整个场景的亮度。等学了光源的知识你会发现,任何一个光源发出的光可分为环境光、散射光、镜面反射光。

这个命令还有另外的用途,最常用的是:

GlLightModelfi(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE):启用多边形双面光照。即多边形的两个面都可以被照到。默认值为GL_FALSE,即多边形正面光照。

下面我们将第2章中正方体的例子适当变化,添加一点全局环境光效果。只需在原来的程序前面添加以下代码:

  1. glEnable(GL_LIGHTING);                  //启用光照  
  2. float V[]={1,1,1,1};                        //光照强度数组  
  3. glLightModelfv(GL_LIGHT_MODEL_AMBIENT,V);   //光照模式(这里是指全局环境光)  
  4. glEnable(GL_COLOR_MATERIAL);                //启用颜色追踪 

最后一句代码需要更多说明:没有此命令,后面的颜色设置将不起作用。事实上这里启用的是物体对光线的反射效果。虽然有环境光照射到物体上,若物体不进行反射,光线就无法到达我们的眼睛,当然我们看到的就是一个黑色的屏幕。启用颜色追踪后,OpenGL会根据后面glColor设置的颜色进行光线反射。这里追踪的颜色就是glColor设置的颜色。

程序运行效果图如下,其中图3-3的V[]={0.5,0.5,0.5,0.5},图3-4的V[]={1,1,1,1};大家比较可以发现这二者之间的亮度差别。这里的差别主要是由全局环境光引起的。另外,对单个图形来说,旋转一下,你可以发现各处的亮度是一样的。

 
图3-3  V[]={0.5,0.5,0.5,0.5}

 
图3-4  V[]={1,1,1,1}

原文地址:https://www.cnblogs.com/xuejinhui/p/4387903.html