10.4.3 材质RGB值和光源RGB值的关系
  材质的颜色与光源的颜色有些不同。对于光源,R、G、B值等于R、G、B对其最大强度的百分比。若光源颜色的R、G、B值都是1.0,则是最强的白光;若值变为0.5,颜色仍为白色,但强度为原来的一半,于是表现为灰色;若R=G=1.0,B=0.0,则光源为黄色。对于材质,R、G、B值为材质对光的R、G、B成分的反射率。比如,一种材质的R=1.0、G=0.5、B=0.0,则材质反射全部的红色成分,一半的绿色成分,不反射蓝色成分。也就是说,若OpenGL的光源颜色为(LR、LG、LB),材质颜色为(MR、MG、MB),那么,在忽略所有其他反射效果的情况下,最终到达眼睛的光的颜色为(LR*MR、LG*MG、LB*MB)。
  同样,如果有两束光,相应的值分别为(R1、G1、B1)和(R2、G2、B2),则OpenGL将各个颜色成分相加,得到(R1+R2、G1+G2、B1+B2),若任一成分的和值大于1(超出了设备所能显示的亮度)则约简到1.0。下面一例程就说明了二者之间的关系。

  例10-4 材质与光源的RGB关系例程(light2.c)

  #include "glos.h"
  #include <GL/gl.h>
  #include <GL/glaux.h>

  void myinit(void);
  void CALLBACK myReshape(GLsizei w, GLsizei h);
  void CALLBACK display(void);

  void myinit(void)
  {
    GLfloat mat_ambient[]= { 0.8, 0.8, 0.8, 1.0 };
    GLfloat mat_diffuse[]= { 0.8, 0.0, 0.8, 1.0 }; 
    GLfloat mat_specular[] = { 1.0, 0.0, 1.0, 1.0 };
    GLfloat mat_shininess[] = { 50.0 };

    GLfloat light_diffuse[]= { 0.0, 0.0, 1.0, 1.0}; 
    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glDepthFunc(GL_LESS);
    glEnable(GL_DEPTH_TEST);
  }

  void CALLBACK display(void)
  {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    auxSolidSphere(1.0);
    glFlush();
  }

  void CALLBACK myReshape(GLsizei w, GLsizei h)
  {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w <= h)
      glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
    else
      glOrtho (-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
  }

  void main(void)
  {
    auxInitDisplayMode (AUX_SINGLE | AUX_RGBA | AUX_DEPTH16);
    auxInitPosition (0, 0, 500, 500);
    auxInitWindow ("Lighting_2 ");
    myinit();
    auxReshapeFunc (myReshape);
    auxMainLoop(display);
  }

  以上程序运行结果是一个蓝色的球,其中高光部分仍为上一例的亮紫色。从上可看出,球漫反射光的结果是mat_diffuse[]与light_diffuse[]中的三个颜色分量值相乘,即 (0.0*1.0,0.0*1.0,0.8*1.0,1.0*1.0)=(0.0,0.0,0.8,1.0),所以球大部分呈现蓝色。

图10-4 光照蓝色球高光为红色

   10.4.4 材质改变
  在实际应用的许多情况下,不同的物体或同一物体的不同部分都有可能设置不同的材质,OpenGL函数库提供了两种方式实现这种要求。下面一例程采用的是设置矩阵堆栈来保存不同物体的材质信息:

   例10-5 矩阵堆栈改变材质例程( chgmat1.c)

   #include "glos.h"
  #include <GL/gl.h>
  #include <GL/glu.h>
  #include <GL/glaux.h>

  void myinit(void);
  void CALLBACK display(void);
  void CALLBACK myReshape(GLsizei w, GLsizei h);

  
   void myinit(void)
  {
    GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
    GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat position[] = { 0.0, 3.0, 2.0, 0.0 };
    GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 1.0 };

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
    glLightfv(GL_LIGHT0, GL_POSITION, position);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    glClearColor(0.0, 0.1, 0.1, 0.0);
  }

  void CALLBACK display(void)
  {
    GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
    GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
    GLfloat mat_ambient_color[] = { 0.8, 0.8, 0.2, 1.0 };
    GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 1.0 };
    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat no_shininess[] = { 0.0 };
    GLfloat low_shininess[] = { 5.0 };
    GLfloat high_shininess[] = { 100.0 };
    GLfloat mat_emission[] = {0.3, 0.2, 0.2, 0.0};

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    
     glPushMatrix();
    glTranslatef (-3.75, 3.0, 0.0);
    glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
    glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
    auxSolidSphere(1.0);
    glPopMatrix();

    
     glPushMatrix();
    glTranslatef (-1.25, 3.0, 0.0);
    glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
    auxSolidSphere(1.0);
    glPopMatrix();

    
     glPushMatrix();
    glTranslatef (1.25, 3.0, 0.0);
    glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
    auxSolidSphere(1.0);
    glPopMatrix();

    
     glPushMatrix();
    glTranslatef (3.75, 3.0, 0.0);
    glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
    glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
    auxSolidSphere(1.0);
    glPopMatrix();

    
     glPushMatrix();
    glTranslatef (-3.75, 0.0, 0.0);
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
    glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
    auxSolidSphere(1.0);
    glPopMatrix();

    
     glPushMatrix();
    glTranslatef (-1.25, 0.0, 0.0);
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
    auxSolidSphere(1.0);
    glPopMatrix();

    
     glPushMatrix();
    glTranslatef (1.25, 0.0, 0.0);
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
    auxSolidSphere(1.0);
    glPopMatrix();

    
     glPushMatrix();
    glTranslatef (3.75, 0.0, 0.0);
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
    glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
    auxSolidSphere(1.0); glPopMatrix();

    
     glPushMatrix();
    glTranslatef (-3.75, -3.0, 0.0);
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
    glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
    auxSolidSphere(1.0);
    glPopMatrix();

    
     glPushMatrix();
    glTranslatef (-1.25, -3.0, 0.0);
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
    auxSolidSphere(1.0);
    glPopMatrix();

    
     glPushMatrix();
    glTranslatef (1.25, -3.0, 0.0);
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
    auxSolidSphere(1.0);
    glPopMatrix();

    
     glPushMatrix();
    glTranslatef (3.75, -3.0, 0.0);
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
    glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
    glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
    auxSolidSphere(1.0);
    glPopMatrix();

    glFlush();
  }

  void CALLBACK myReshape(GLsizei w, GLsizei h)
  {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w <= (h * 2))
      glOrtho (-6.0, 6.0, -3.0*((GLfloat)h*2)/(GLfloat)w,
        3.0*((GLfloat)h*2)/(GLfloat)w, -10.0, 10.0);
    else
      glOrtho (-6.0*(GLfloat)w/((GLfloat)h*2),
        6.0*(GLfloat)w/((GLfloat)h*2), -3.0, 3.0, -10.0, 10.0);
    glMatrixMode(GL_MODELVIEW);
  }

  void main(void)
  {
    auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);
    auxInitPosition (0, 0, 600, 450);
    auxInitWindow ("Material");
    myinit();
    auxReshapeFunc (myReshape);
    auxMainLoop(display);
  }

图10-5 多种光和材质的变化效果

  以上程序运行结果是绘制12个球(3行4列)。第一行的球材质都没有环境反射光,第二行的都有一定的环境反射光,第三行的都有某种颜色的环境光。而第一列的球材质仅有蓝色的漫反射光;第二列的不仅有蓝漫反射光,而且还有镜面反射光,较低的高光;第三列的不仅有蓝漫反射光,而且还有镜面反射光,很亮的高光;第四列的还包括辐射光,但无镜面光。
  这个程序运用矩阵堆栈多次调用glMaterialfv()来设置每个球的材质,也就是改变同一场景中的不同物体的颜色。但由于这个函数的应用有个性能开销,因此建议最好尽可能少的改变材质,以减少改变材质时所带来的性能开销,可采用另一种方式即改变材质颜色,相应函数为glColorMaterial(),说明如下:

   void glColorMaterial(GLenum face,GLenum mode);

  函数参数face指定面,值有GL_FRONT、GL_BACK或GL_FRONT_AND_BACK(缺省值)。mode指定材质成分,值有GL_AMBIENT、GL_DIFFUSE、GL_AMBIENT_AND_DIFFUSE(缺省值)、GL_SPECULAR或GLEMISSION。
   注意:这个函数说明了两个独立的值,第一个参数说明哪一个面和哪些面被修改,而第二个参数说明这些面的哪一个或哪些材质成分要被修改。OpenGL并不为每一种face保持独立的mode变量。在调用glColorMterial()以后,首先需要用GL_COLOR_MATERIAL作为参数调用glEnable()来启动颜色材质,然后在绘图时调用glColor*()来改变当前颜色,或用glMaterial()来改变材质成分。当不用这种方式来改变材质时,可调用glDisable(GL_COLOR_MATERIAL)来关闭取消。如下面一段代码:

   glColorMaterial(GL_FRONT,GL_DIFFUSE);
  glEnable(GL_COLOR_MATERIAL);
  glColor3f(0.3,0.5,0.7);
  
   glcolor3f(0.0,1.0,0.0);
  
   glDisable(GL_COLOR_MATERIAL);

  当需要改变场景中大部分方面的单个材质时,最好调用glColorMaterial();当需要修改不止一个材质参数时,最好调用glMaterial*()。注意,当不需要颜色材质时一定要关闭它,以避免相应的开销。下面来看一个颜色材质的具体应用例子:

   例10-6 颜色定义改变材质例程( chgmat2.c)

   #include "glos.h"?
  #include <GL/gl.h>
  #include <GL/glu.h>
  #include <GL/glaux.h>

  void myinit(void);
  void CALLBACK myReshape(GLsizei w, GLsizei h);
  void CALLBACK display(void);

  void myinit(void)
  {
    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glDepthFunc(GL_LESS);
    glEnable(GL_DEPTH_TEST);

    glColorMaterial(GL_FRONT, GL_DIFFUSE);
    glEnable(GL_COLOR_MATERIAL);
  }

  void CALLBACK display(void)
  {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    
     glLoadIdentity();
    glTranslatef(-0.7,0.0,0.0);
    glColor3f(1.0,1.0,0.0);
    auxSolidSphere(0.5);

    
     glLoadIdentity();
    glRotatef(-65.0,1.0,0.0,0.0);
    glTranslatef(0.7,0.0,0.0);
    glColor3f(1.0,0.0,0.0);
    auxSolidCone(0.4,0.6);

    glFlush();
  }

  void CALLBACK myReshape(GLsizei w, GLsizei h)
  {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w <= h)
      glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
    else
      glOrtho (-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
  }

  void main(void)
  {
    auxInitDisplayMode (AUX_SINGLE | AUX_RGB | AUX_DEPTH16);
    auxInitPosition (0, 0, 500, 500);
    auxInitWindow ("ColorMaterial Mode");
    myinit();
    auxReshapeFunc (myReshape);
    auxMainLoop(display);
  }

  以上程序改变的是漫反射颜色。场景中显示了一个黄色的球和一个红色的锥体。

图10-6 漫反射材质改变

OpenGL材质和光照(转)part2相关推荐

  1. OpenGL材质和光照(转)part1

    真实感图形绘制是计算机图形学的一个重要组成部分,它综合利用数学.物理学.计算机科学和其它科学知识在计算机图形设备上生成象彩色照片那样的具有真实感的图形.一般说来,用计算机在图形设备上生成真实感图形必须 ...

  2. OpenGL材质Materials

    OpenGL材质Materials 材质Materials简介 设置材质 光的属性 不同的光源颜色 材质Materials简介 在现实世界里,每个物体会对光产生不同的反应.比如说,钢看起来通常会比陶瓷 ...

  3. OpenGL ES 3. 光照-散射光

    大家好,接下来将为大家介绍OpenGL ES 3. 光照-散射光. OpenGL ES 3.0 中采用的光照模型相对现实世界进行了很大的简化,将光照分成了 3 种组成元素(也可以称为 3 个通道),包 ...

  4. OpenGL学习之光照中的材质

    本文参考LearnOpenGL CN 在现实世界中,每个物体会对光产生不同的反应.比如:钢看起来通常会比陶瓷瓶更闪闪发光,木头箱子也不会像钢制箱子那样对光产生很强的反射.每个梧桐对镜面高光也有不同的反 ...

  5. [OpenGL] 茶壶与光照

    OpenGL可以设置至少8种光源,它们的标号为GL_LIGHT0,GL_LIGHT1,GL_LIGHT2--.在这里我们使用了两种光源,一种是环境光,另一种是聚光灯. 在设置光照时,我们需要考虑这样三 ...

  6. 进阶光照与材质之光照和反射模型

    第五章讲述了一些漫反射模型和镜面反射模型的原理和数学公式 博主在unity中实现了一下,把部分结果贴在上面 有下面几个主题: 渲染公式 基本光照定义 光照和lambert法则 双向反射分布函数BRDF ...

  7. URP——着色器和材质——复杂光照Complex Lit

    Complex Lit Shader 复杂的灯光着色器包含了灯光着色器的所有功能,并添加了高级的材质特性.一些特性在这个着色器可能是相当多的资源密集型和需要Unity Shader Model 4.5 ...

  8. URP——着色器和材质——烘焙光照 Baked Lit

    Baked Lit Shader 在通用渲染管道(URP)中,对于只需要通过光照贴图和光照探测烘烤的游戏或应用程序使用此着色器.这个着色器不使用基于物理的阴影和没有实时照明,所以所有实时相关的着色器关 ...

  9. 【OpenGL学习】光照贴图

    光照贴图 上节中我们给物体添加了材质,使得物体能够对光照做出不同的反应,但是有个问题就是,使用该种材质的物体,只能够表现出我们所定义的一种性质,而实际生活中我们的一个物体往往具有多种材质,因此本节中我 ...

最新文章

  1. OnlineJudge在线判题系统
  2. Git之深入解析本地仓库的基本操作·仓库的获取更新和提交历史的查看撤销以及标签别名的使用
  3. 单例模式懒汉式(线程安全写法)
  4. JavaFX技巧13:学习Modena CSS文件
  5. web api教程Java_WebApi项目创建CURD
  6. java 是怎么在中删除下拉列表_java中下拉菜单如何清空
  7. ie不兼容的几个js问题及解决办法
  8. “三低”用户养活的互联网
  9. Python爬虫编程思想(92):项目实战:抓取京东图书评价
  10. wifi模块和51单片机相连的问题
  11. 华硕X370 Pro更新BIOS后黑屏自救记录
  12. 华为防火墙及它的工作原理
  13. Android自定义View 实现窗帘控件
  14. linux 上 gcc -m32 编译报错解决方案
  15. 原码 反码 补码 移码(变补)补码与移码的作用
  16. 如何准备面试?“-80,阿里Java开发面试解答
  17. StringBuffer是安全的吗?
  18. 高通字库芯片GT20L16S1Y驱动 0.96寸 OLED 任意显示中文
  19. Android Studio使用真机(连接安卓手机驱动)调试教程
  20. undefined reference to `OsqpEigen::Solver::lu_solve()‘问题解决

热门文章

  1. 弹出查看图片_报表工具如何实现“点击查看原图”
  2. gitlab数据迁移
  3. 大佬来告诉你在遇到B站崩了,如何防止类似事故的出现?
  4. Linux的文件管理命令
  5. python创建文件夹命令_python文件操作指令
  6. java滥用接口_吐槽一下项目中的代码坏味道:滥用java常量
  7. ae制h5文字动画_AE动画在H5设计中的应用研究
  8. HTML5 服务器发送事件(Server-Sent Events)介绍
  9. PIC单片机学习之独立按键
  10. Android 关于::app:clean :app:preBuild UP-TO-DATE :app:preDebugBuild UP-TO-DATE,引用jar冲突问题...