光的光源(Light source)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了光的光源(Light source)相关的知识,希望对你有一定的参考价值。

参考技术A

光源主要可以分为三类。
第一类是热效应产生的光。太阳光就是很好的例子,此外蜡烛等物品也都一样,此类光随着温度的变化会改变颜色。
第二类是原子跃迁发光。荧光灯灯管内壁涂抹的荧光物质被电磁波能量激发而产生光。此外霓虹灯的原理也是一样。原子发光具有独自的特征谱线。科学家经常利用这个原理鉴别元素种类。
第三类是物质内部带电粒子加速运动时所产生的光。譬如,同步加速器(synchrotron)工作时发出的同步辐射光,同时携带有强大的能量。另外,原子炉(核反应堆)发出的淡蓝色微光(切伦科夫辐射)也属于这种。

OpenGL glLightfv 函数的应用以及光源的相关知识

事实上光源才是所有光照效果的基础,没有光源一切都无从谈起。OpenGL中我们可以设置8个光源,其编号分别为GL_LIGHT0、GL_LIGHT1、……、GL_LIGHT7。就相当于现实生活中有8个太阳,但每个太阳的位置、方向及它发出的光线可以完全不同。因此,OpenGL中我们设置光源时,主要就是设置其颜色、位置、方向等性质。另外,OpenGL中任何一个光源都可以发出不同强度的环境光、散射光、镜面反射光,这几个方面综合起来就决定了光源的颜色。

我们通过glLightfv(光源编号,光源特性,参数数据)来设置光源。其中,光源编号可取GL_LIGHT0、GL_LIGHT1、……、GL_LIGHT7共8个值。光源特性主要可取GL_AMBIENT(设置光源的环境光属性,默认值(0,0,0,1))、GL_DIFFUSE(设置光源的散射光属性,默认值(1,1,1,1))、GL_SPECULAR(设置光源的镜面反射光属性,默认值(1,1,1,1))、GL_POSITION(设置光源的位置,默认值(0,0,1,0))。参数数据格式要求为数组形式,即数学上的向量形式。

下面一段代码,我们将一个光源的性质进行完整设置:

 
  1. GLfloat Va[]=0.4,0.4,0.4,1;           //光源环境光强度数组  
  2. GLfloat Vd[]=0.6,0.6,0.6,1;           //光源散射光强度数组  
  3. GLfloat Vs[]=0.6,0.6,0.6,1;           //光源镜面反射光强度数组  
  4. GLfloat Vp[]=1,1,1,1;             //光源位置数组  
  5. glLightfv(GL_LIGHT0,GL_AMBIENT,Va); //设置0号光源的环境光属性  
  6. glLightfv(GL_LIGHT0,GL_DIFFUSE,Vd); //设置0号光源的散射光属性  
  7. glLightfv(GL_LIGHT0,GL_SPECULAR,Vs);    //设置0号光源的镜面反射光属性  
  8. glLightfv(GL_LIGHT0,GL_POSITION,Vp);    //设置0号光源的位置属性  

光源的性质设置完毕,还要调用glEnable(GL_LIGHT0)来打开光源。就相当于你买回手电筒、装好电池(设置光源),但如果不打开开关(打开电源),手电筒是不起作用的。

另外,对于GL_POSITION,其位置数组(x,y,z,w)定义了光源在空间中的位置。但三维空间为什么需要4个量呢?事实上这里采用的是齐次坐标,当w≠0时,它表示光源处于空间中(x,y,z)处,这时的光源称为定点光源;当w=0时,根据齐次坐标的性质,它表示光源位于无穷远处,此时光源称为定向光源,其所有光线几乎是相互平等的,如太阳。其光线方向由点(x,y,z)指向(0,0,0)。

将第2章中的正方体的例子做以下修改。修改后的void __fastcall TForm1::OpenGL1 GLPaint(TObject *Sender)处的代码如下(其余位置不变):

 
  1. void __fastcall TForm1::OpenGL1GLPaint(TObject *Sender)  
  2.  
  3.   glEnable(GL_DEPTH_TEST);          //隐藏表面消除  
  4.   glClear(GL_DEPTH_BUFFER_BIT); //清除窗口颜色  
  5.  
  6.   const GLfloat glfLightAmbient1[4] = 0.1, 0.1, 0.1, 1.0;  
  7.   const GLfloat glfLightAmbient2[4] = 0.4, 0.4, 0.4, 1.0;  
  8.   const GLfloat glfLightDiffuse1[4] = 0, 0.8, 0.8, 1.0;  
  9.   const GLfloat glfLightDiffuse2[4] = 0.8, 0.8, 0.8, 1.0;  
  10.   const GLfloat glfLightSpecular1[4] = 0, 0.8, 0.8, 1.0;  
  11.   const GLfloat glfLightSpecular2[4] = 0.8, 0.8, 0.8, 1.0;  
  12.   const GLfloat glPosition1[4]=0,0,1,0;  
  13.   const GLfloat glPosition2[4]=0.6,0.6,-0.6,1;  
  14.   glLightfv(GL_LIGHT0, GL_AMBIENT,  glfLightAmbient1);  
  15.   glLightfv(GL_LIGHT0, GL_DIFFUSE,  glfLightDiffuse1);  
  16.   glLightfv(GL_LIGHT0, GL_SPECULAR, glfLightSpecular1);  
  17.   glLightfv(GL_LIGHT0,GL_POSITION,glPosition1);  
  18.   glLightfv(GL_LIGHT1, GL_AMBIENT,  glfLightAmbient2);  
  19.   glLightfv(GL_LIGHT1, GL_DIFFUSE,  glfLightDiffuse2);  
  20.   glLightfv(GL_LIGHT1, GL_SPECULAR, glfLightSpecular2);  
  21.   glLightfv(GL_LIGHT1,GL_POSITION,glPosition2);  
  22.   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);//两面照亮  
  23.       glEnable(GL_LIGHTING);//启用光照  
  24.       glEnable(GL_LIGHT0);  
  25.       glEnable(GL_LIGHT1);//打开光源  
  26.       glEnable(GL_COLOR_MATERIAL);//启用颜色追踪  
  27.       glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);  
  28. //物体正面的材料环境颜色和散射颜色,追踪glColor所设置的颜色(比较拗口,
    事实上就是让OpenGL根据glColor所设置的颜色自动设置物体的反射强度)  
  29.  
  30.   glShadeModel(GL_FLAT);//设置颜色填充模式  
  31.    glBegin(GL_QUAD_STRIP) ;  
  32.      glVertex3f(i,-i,i);  
  33.      glVertex3f(i,-i,-i);  
  34.      glColor3f(1,0,0);  
  35.      glVertex3f(-i,-i,i);  
  36.      glVertex3f(-i,-i,-i);  
  37.      glColor3f(0,1,0);  
  38.      glVertex3f(-i,i,i);  
  39.      glVertex3f(-i,i,-i);  
  40.      glColor3f(0,0,1);  
  41.      glVertex3f(i,i,i);  
  42.      glVertex3f(i,i,-i);  
  43.      glColor3f(1,1,0);  
  44.      glVertex3f(i,-i,i);  
  45.      glVertex3f(i,-i,-i);  
  46.    glEnd();  
  47.    glBegin(GL_QUADS);  
  48.      glVertex3f(i,-i,i);  
  49.      glVertex3f(-i,-i,i);  
  50.      glVertex3f(-i,i,i);  
  51.      glColor3f(1,0,1);  
  52.      glVertex3f(i,i,i);  
  53.  
  54.      glVertex3f(i,-i,-i);  
  55.      glVertex3f(-i,-i,-i);  
  56.      glVertex3f(-i,i,-i);  
  57.      glColor3f(0,1,1);  
  58.      glVertex3f(i,i,-i);  
  59.    glEnd();  
  60.  
  61.       glDisable(GL_LIGHTING);//关闭光照  
  62.       glDisable(GL_LIGHT0);//关闭0号光源  
  63.       glDisable(GL_LIGHT1); //关闭1号光源  
  64.  

程序运行效果如图3-5和图3-6所示(旋转一下可以发现,图形的3D效果同第2章相比有了长足的进步。第2章中感觉像是几个放置在空间中的木板,现在的第一感觉就是空间中的正方体)。

效果图见路径  http://book.51cto.com/art/201104/255655.htm


以上是关于光的光源(Light source)的主要内容,如果未能解决你的问题,请参考以下文章

关于Unity中的光照

光源设计

Unity-LightMap

0基础尝试实现UnityURP渲染管线的AdditionalLit(点光源,聚光灯)非平行光的光照模型代码

Google android source code build 问题总结

OpenGL glLightfv 函数的应用以及光源的相关知识