光的光源(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))。参数数据格式要求为数组形式,即数学上的向量形式。
下面一段代码,我们将一个光源的性质进行完整设置:
- GLfloat Va[]=0.4,0.4,0.4,1; //光源环境光强度数组
- GLfloat Vd[]=0.6,0.6,0.6,1; //光源散射光强度数组
- GLfloat Vs[]=0.6,0.6,0.6,1; //光源镜面反射光强度数组
- GLfloat Vp[]=1,1,1,1; //光源位置数组
- glLightfv(GL_LIGHT0,GL_AMBIENT,Va); //设置0号光源的环境光属性
- glLightfv(GL_LIGHT0,GL_DIFFUSE,Vd); //设置0号光源的散射光属性
- glLightfv(GL_LIGHT0,GL_SPECULAR,Vs); //设置0号光源的镜面反射光属性
- 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)处的代码如下(其余位置不变):
- void __fastcall TForm1::OpenGL1GLPaint(TObject *Sender)
- glEnable(GL_DEPTH_TEST); //隐藏表面消除
- glClear(GL_DEPTH_BUFFER_BIT); //清除窗口颜色
- const GLfloat glfLightAmbient1[4] = 0.1, 0.1, 0.1, 1.0;
- const GLfloat glfLightAmbient2[4] = 0.4, 0.4, 0.4, 1.0;
- const GLfloat glfLightDiffuse1[4] = 0, 0.8, 0.8, 1.0;
- const GLfloat glfLightDiffuse2[4] = 0.8, 0.8, 0.8, 1.0;
- const GLfloat glfLightSpecular1[4] = 0, 0.8, 0.8, 1.0;
- const GLfloat glfLightSpecular2[4] = 0.8, 0.8, 0.8, 1.0;
- const GLfloat glPosition1[4]=0,0,1,0;
- const GLfloat glPosition2[4]=0.6,0.6,-0.6,1;
- glLightfv(GL_LIGHT0, GL_AMBIENT, glfLightAmbient1);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, glfLightDiffuse1);
- glLightfv(GL_LIGHT0, GL_SPECULAR, glfLightSpecular1);
- glLightfv(GL_LIGHT0,GL_POSITION,glPosition1);
- glLightfv(GL_LIGHT1, GL_AMBIENT, glfLightAmbient2);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, glfLightDiffuse2);
- glLightfv(GL_LIGHT1, GL_SPECULAR, glfLightSpecular2);
- glLightfv(GL_LIGHT1,GL_POSITION,glPosition2);
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);//两面照亮
- glEnable(GL_LIGHTING);//启用光照
- glEnable(GL_LIGHT0);
- glEnable(GL_LIGHT1);//打开光源
- glEnable(GL_COLOR_MATERIAL);//启用颜色追踪
- glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
- //物体正面的材料环境颜色和散射颜色,追踪glColor所设置的颜色(比较拗口,
事实上就是让OpenGL根据glColor所设置的颜色自动设置物体的反射强度)- glShadeModel(GL_FLAT);//设置颜色填充模式
- glBegin(GL_QUAD_STRIP) ;
- glVertex3f(i,-i,i);
- glVertex3f(i,-i,-i);
- glColor3f(1,0,0);
- glVertex3f(-i,-i,i);
- glVertex3f(-i,-i,-i);
- glColor3f(0,1,0);
- glVertex3f(-i,i,i);
- glVertex3f(-i,i,-i);
- glColor3f(0,0,1);
- glVertex3f(i,i,i);
- glVertex3f(i,i,-i);
- glColor3f(1,1,0);
- glVertex3f(i,-i,i);
- glVertex3f(i,-i,-i);
- glEnd();
- glBegin(GL_QUADS);
- glVertex3f(i,-i,i);
- glVertex3f(-i,-i,i);
- glVertex3f(-i,i,i);
- glColor3f(1,0,1);
- glVertex3f(i,i,i);
- glVertex3f(i,-i,-i);
- glVertex3f(-i,-i,-i);
- glVertex3f(-i,i,-i);
- glColor3f(0,1,1);
- glVertex3f(i,i,-i);
- glEnd();
- glDisable(GL_LIGHTING);//关闭光照
- glDisable(GL_LIGHT0);//关闭0号光源
- glDisable(GL_LIGHT1); //关闭1号光源
程序运行效果如图3-5和图3-6所示(旋转一下可以发现,图形的3D效果同第2章相比有了长足的进步。第2章中感觉像是几个放置在空间中的木板,现在的第一感觉就是空间中的正方体)。
效果图见路径 http://book.51cto.com/art/201104/255655.htm
以上是关于光的光源(Light source)的主要内容,如果未能解决你的问题,请参考以下文章
0基础尝试实现UnityURP渲染管线的AdditionalLit(点光源,聚光灯)非平行光的光照模型代码