3.2 光照篇(2)

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

3.2   光照篇(2)

2.光源

事实上光源才是所有光照效果的基础,没有光源一切都无从谈起。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. const GLfloat glfLightAmbient1[4] = {0.1, 0.1, 0.1, 1.0};
  6. const GLfloat glfLightAmbient2[4] = {0.4, 0.4, 0.4, 1.0};
  7. const GLfloat glfLightDiffuse1[4] = {0, 0.8, 0.8, 1.0};
  8. const GLfloat glfLightDiffuse2[4] = {0.8, 0.8, 0.8, 1.0};
  9. const GLfloat glfLightSpecular1[4] = {0, 0.8, 0.8, 1.0};
  10. const GLfloat glfLightSpecular2[4] = {0.8, 0.8, 0.8, 1.0};
  11. const GLfloat glPosition1[4]={0,0,1,0};
  12. const GLfloat glPosition2[4]={0.6,0.6,-0.6,1};
  13. glLightfv(GL_LIGHT0, GL_AMBIENT,  glfLightAmbient1);
  14. glLightfv(GL_LIGHT0, GL_DIFFUSE,  glfLightDiffuse1);
  15. glLightfv(GL_LIGHT0, GL_SPECULAR, glfLightSpecular1);
  16. glLightfv(GL_LIGHT0,GL_POSITION,glPosition1);
  17. glLightfv(GL_LIGHT1, GL_AMBIENT,  glfLightAmbient2);
  18. glLightfv(GL_LIGHT1, GL_DIFFUSE,  glfLightDiffuse2);
  19. glLightfv(GL_LIGHT1, GL_SPECULAR, glfLightSpecular2);
  20. glLightfv(GL_LIGHT1,GL_POSITION,glPosition2);
  21. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);//两面照亮
  22. glEnable(GL_LIGHTING);//启用光照
  23. glEnable(GL_LIGHT0);
  24. glEnable(GL_LIGHT1);//打开光源
  25. glEnable(GL_COLOR_MATERIAL);//启用颜色追踪
  26. glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
  27. //物体正面的材料环境颜色和散射颜色,追踪glColor所设置的颜色(比较拗口,
    事实上就是让OpenGL根据glColor所设置的颜色自动设置物体的反射强度)
  28. glShadeModel(GL_FLAT);//设置颜色填充模式
  29. glBegin(GL_QUAD_STRIP) ;
  30. glVertex3f(i,-i,i);
  31. glVertex3f(i,-i,-i);
  32. glColor3f(1,0,0);
  33. glVertex3f(-i,-i,i);
  34. glVertex3f(-i,-i,-i);
  35. glColor3f(0,1,0);
  36. glVertex3f(-i,i,i);
  37. glVertex3f(-i,i,-i);
  38. glColor3f(0,0,1);
  39. glVertex3f(i,i,i);
  40. glVertex3f(i,i,-i);
  41. glColor3f(1,1,0);
  42. glVertex3f(i,-i,i);
  43. glVertex3f(i,-i,-i);
  44. glEnd();
  45. glBegin(GL_QUADS);
  46. glVertex3f(i,-i,i);
  47. glVertex3f(-i,-i,i);
  48. glVertex3f(-i,i,i);
  49. glColor3f(1,0,1);
  50. glVertex3f(i,i,i);
  51. glVertex3f(i,-i,-i);
  52. glVertex3f(-i,-i,-i);
  53. glVertex3f(-i,i,-i);
  54. glColor3f(0,1,1);
  55. glVertex3f(i,i,-i);
  56. glEnd();
  57. glDisable(GL_LIGHTING);//关闭光照
  58. glDisable(GL_LIGHT0);//关闭0号光源
  59. glDisable(GL_LIGHT1); //关闭1号光源
  60. }

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

 
图3-5  原始效果图
 
图3-6  增加光照后的效果图

【责任编辑:云霞 TEL:(010)68476606】

时间: 2025-01-31 08:29:07

3.2 光照篇(2)的相关文章

3.2 光照篇(1)

http://book.51cto.com/art/201104/255654.htm 3.2   光照篇(1) 大家之所以能够看到东西,主要是因为物体上有光进入大家的眼睛,无论这个光的来源如何.假若,一个物体自身并不发光而且不反射任何光线,那么把它放到最强的阳光下你也看不到什么.因此,OpenGL中既要设置光线性质,又要设置物体的反射性质(告诉OpenGL,光线如何进入我们的眼睛). 1.光线的分类及设置 OpenGL中的光主要有以下4种:自发光.环境光(ambient).散射光(diffus

诗经 全文

诗经 全文 (带注释和译文) http://www.edu009.com/Article/HTML/Article_60756.html <诗经> 春秋·孔丘 <诗经>是我国第一部诗歌总集,先秦时代称为“诗”或“诗三百”,孔子加以了整理.汉武帝采纳董仲舒“罢黜百家,独尊儒术”的建议,尊“诗”为经典,定名为<诗经>. <诗经>现存诗歌 305 篇,包括西周初年到春秋中叶共 500 余年的民歌和朝庙乐章,分为风.雅.颂三章. “风”包括周南.召南.邶.鄘.卫.王

【浅墨Unity3D Shader编程】之七 静谧之秋篇: 表面着色器的写法(二)——自定义光照模式

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://hpw123.net/plus/view.php?aid=183 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文主要讲解了Unity中SurfaceShader的自定义光照模式的写法. 上篇文章中我们已经说到,表面着色器将分为两次讲解,上

【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&amp;颜色、光照与材质

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 本篇文章中,我们学习了Unity Shader的基本写法框架,以及学习了Shader中Properties(属性)的详细写法,光照.材质与颜色的具体写法.写了6个Shader作为本文S

全局光照技术进化史1-光线追踪篇

本来计划是最近一年专心写书,不要花心思和精力写博客的,因为写一篇优质的博客文章其实也要花费不少的时间构思的:单篇博客虽然文字少但是你可能需要花费更多的精力在有限的篇幅内包括更多上下文信息,以及更精简地组织内容,在我看来它的创作付出不亚于图书内容写作(当然如果作者对自己要求没那么严谨的话可能也没那么严重). <游戏引擎全局光照技术>采取了一种新的出版形式,它从写作第一章开始,就积极和社区互动并开始宣传,其方式和游戏发行的思路一致:即在开发阶段不断推出测试版积极和玩家互动,并收集反馈信息进行持续改

OpenGL编程 基础篇(六)OpenGL中几种光照参数

一.定义 1.GL_AMBIENT:环境光,经过很多次反射后最终遗留在环境中的光线强度(颜色). 2.GL_DIFFUSE:漫反射,表示光线照射到该材质上,经过漫反射后形成的光线强度(颜色). 3.GL_SPECULAR:镜面反射,表示光线照射到该材质上,经过镜面反射后形成的光线强度(颜色). 注:通常,GL_AMBIENT和GL_DIFFUSE都取相同的值,可以达到比较真实的效果.使用GL_AMBIENT_AND_DIFFUSE可以同时设置GL_AMBIENT和GL_DIFFUSE属性. 4.

Unity3D教程宝典之Shader篇:第十五讲 光照基础

转载自风宇冲Unity3D教程学院 简单的说,带光照的Shader的最终颜色输出为 材质颜色 * 光颜色,其中 材质颜色:之前已经提到过,固定格式tex2D (_MainTex, i.uv) 光颜色:光颜色 = 自发光 + 环境光 + 漫反射光 + 镜面光 下面详细讲解这四种光 一:自发光 由物体表面向四面八方发出的光 emissive = colorEmissive colorEmissive 自发光的颜色 二:环境光 物体表面接收的来自四面八方发出的光, 然后向四面八方反射 ambient

Unity预计算全局光照的学习(速度优化,LightProbe,LPPV)

1.基本参数与使用 1.1 常规介绍 使用预计算光照需要在Window/Lighting面板下找到预计算光照选项,保持勾选预计算光照并保证场景中有一个光照静态的物体 此时在编辑器内构建后,预计算光照开始生效. 相关的文章有很多,unity官方有一系列文章不错: https://unity3d.com/cn/learn/tutorials/topics/graphics/introduction-precomputed-realtime-gi 在Lighting面板的Scene页签下可以设置全局光

【Unity Shaders】Shader中的光照

写在前面 自己写过Vertex & Fragment Shader的童鞋,大概都会对Unity的光照痛恨不已.当然,我相信这是因为我们写得少...不过这也是由于官方文档对这方面介绍很少的缘故,导致我们无法自如地处理很多常见的光照变量.这篇我们就来讨论下Unity内置的一些光照变量和函数到底怎么用. 以下内容均建立在Forward Rendering Path的基础上. 自己总结的,如果有硬伤一定要告诉我啊!感激不尽~ 主要参考: http://en.wikibooks.org/wiki/Cg_P