OpenGL 光照变化:环境到漫反射或镜面反射有效,但不是相反

Posted

技术标签:

【中文标题】OpenGL 光照变化:环境到漫反射或镜面反射有效,但不是相反【英文标题】:OpenGL Light changes : Ambient to Diffuse or Specular works but not the opposite 【发布时间】:2012-04-16 20:27:23 【问题描述】:

我在 OpenGL 中遇到了灯光问题:

我用这段代码改变了我的球灯:

switch(option)                                             
case ambient:                                               
  glLightfv(GL_LIGHT0,GL_AMBIENT,lum_ambient);              
  glMaterialfv(GL_FRONT,GL_SPECULAR,mat_ambient);           
  break;                                                    
case diffuse:                                               
  glLightfv(GL_LIGHT0,GL_DIFFUSE,lum_diffuse);              
  glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);            
  break;                                                    
case specular:                                              
  glLightfv(GL_LIGHT0,GL_SPECULAR,lum_speculaire);          
  glMaterialfv(GL_FRONT,GL_SPECULAR,mat_speculaire);        
  break;                                                    
     

我可以从 Ambient 更改为漫反射或镜面反射。但是一旦我改变了,我就不能回到环境,更糟糕的是:要回到漫反射,我需要调用环境。

而且我不认为它来自这段代码:

   switch (key)                               
   case 27:                                    
       exit(1);                                
   case '1':                                   
     option = ambient;                         
     glutPostRedisplay();                      
     break;                                    
   case '2':                                   
     option = diffuse;                         
     glutPostRedisplay();                      
     break;                                    
   case '3':                                   
     option = specular;                        
     glutPostRedisplay();                      
     break;                                    
     

知道我的问题来自哪里吗?

【问题讨论】:

【参考方案1】:

问题来自这样一个事实,即状态不会因为您更改了一些 other 状态而消失。如果你有两个全局变量:

int x;
int y;

更改y 不会影响x。如果你有这个 switch 语句:

switch(option)

case ambient:
  x = 4;
  break;
case diffuse:
  y = 6;
  break;
...

如果你用diffuse执行这个,然后用ambient执行它,y的值是多少? 还是 6。当然是,因为你没有改变它。

OpenGL 中没有“环境”、“漫反射”或“镜面反射”光照。这些中的每一个都只是每个灯的照明模型中的不同术语。也就是说,OpenGL 总是为每个灯光执行所有这些。您看不到高光照明组件的任何效果的原因是初始高光材质颜色为。这会产生一个零镜面光照组件。

一旦您更改了高光材质颜色,它将保持新值,直到您再次更改它。如果要“关闭”镜面光照,则需要将镜面材质颜色重置为零。其他人也一样。


您正尝试在三种照明模型的设置和默认设置之间切换。所以你必须真正做到这一点:你必须将值重置为 OpenGL 默认值。这些可以在 OpenGL 规范中找到。

除了材质颜色之外,您还必须设置光强度。

如果您不想查看规范,这里是默认值:

环境光:(0.0, 0.0, 0.0, 1.0) 环境材质:(0.2, 0.2, 0.2, 1.0) 漫射光:(1.0, 1.0, 1.0, 1.0)(仅适用于light0。所有其他灯光默认为(0.0 0.0, 0.0, 1.0) 漫射材质:(0.8, 0.8, 0.8, 1.0) 镜面光:(1.0, 1.0, 1.0, 1.0)(仅适用于light0。所有其他灯光默认为(0.0 0.0, 0.0, 1.0) 镜面材质:(0.0 0.0, 0.0, 1.0)

【讨论】:

我开始明白了。但是我是否必须重置 glMaterial 或 glLight 或两者兼而有之? @Matthieu: ahem "如果你想'关闭'高光照明,那么你需要重置高光材质 颜色归零。” 嗯,这就是我所做的,但是用我的环境光和镜面光获得一个黑球。 (我将 GL_DIFFUSE 重置为 0.0,0.0,0.0,1.0) @MatthieuRiegler:抱歉,请参阅我的编辑。我忘记了 OpenGL 的光照模型是愚蠢的。真的,切换到着色器;你会帮大家一个忙。【参考方案2】:

首先,我会使用不同的灯光,而不仅仅是 Light0。另外,请尝试在打开新灯之前关闭所有灯:

glDisable(GL_LIGHT0);

一些帮助:Light source - OPENGL

【讨论】:

以上是关于OpenGL 光照变化:环境到漫反射或镜面反射有效,但不是相反的主要内容,如果未能解决你的问题,请参考以下文章

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

Linux OpenGL 实践篇-6 光照

OpenGL中的光照问题

OpenGL入门04.光照

Vertex中实现每顶点光照的镜面高光效果

图形学计算机图形学知识点提纲10