OpenGL中设置光照的镜面反射效果

时间:2021-12-30 04:12:44
      OpenGL中设置光照的镜面反射效果

     在上一篇笔记中,我们记述了光线的方向与多边形表面的角度计算关系,除此之外,我们还有光源的位置需要指定。我们在ChangeSize函数的内部指定光源的位置:

     // 指定光源的位置
     GLfloat lightPos[] = {-50.0f, 50.0f, 100.0f, 1.0f};
     glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

     在此,lightPos数组包含了光源的坐标位置。这个数组的最后一个值是1.0,表示指定的坐标是光源的位置;如果这个数组的最后一个值是0.0,则表示光是从无限远处沿这个数组所指定的方向向量照射过来的。同样地,光就像几何物体一样,它们也可以根据模型视图矩阵进行移动。
     接下来,我们设置光照的镜面亮点效果。

     镜面亮点
     镜面光和材料的镜面反射属性可以为物体的表面添加必要的光泽。光泽对物体的颜色具有变白的作用,它可以产生镜面加亮的效果。所谓镜面加亮,就是几乎所有光线都照射在一个物体的表面并反射下来。像我们平时看到的日光照射下的金属球,就是一个镜面加亮的例子,如下图所示:

    OpenGL中设置光照的镜面反射效果

     首先,在光照中添加镜面光成分:

     // 指定镜面光强度(RGBA)
     GLfloat specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
     glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
     // 启用光照计算
     glEnable(GL_LIGHTING);
     // 启用光源0
     glEnable(GL_LIGHT0);

     在上述代码中,specular数组为光照的镜面光成分指定了一种非常亮的白色光源。但是现在,如果只是设置了光源部分,我们将无法看到物体的外观有何不同,因为我们还没有定义任何材料的镜面反射属性。
     
     指定材料的镜面反射
     为材料添加镜面反射属性,类似于为光源添加镜面光成分,代码如下所示:

     // 指定材料的镜面反射属性
     GLfloat specref[] = {1.0f, 1.0f, 1.0f, 1.0f};
     // 设置多边形正面的镜面反射属性
     glMaterialfv(GL_FRONT, GL_SPECULAR, specref);
     // 指定镜面指数
     glMateriali(GL_FRONT, GL_SHININESS, 128);

     在这里,我们单独指定了镜面反射属性,specref数组包含了镜面反射的RGBA强度值。如果这个数组的所有值均为1,那么它所产生的表面将会反射几乎所有的入射光。

     指定镜面指数
     强度大的镜面光和反射属性能够加强物体的颜色。不过,极端强烈的镜面光(完全强度)和镜面反射(完全反射)会导致我们的物体几乎呈现纯白色或纯灰色,只有远离光源的那些表面除外。为了抑制这种效果,我们在指定了镜面反射属性之后,需要继续设置一下材料的镜面指数:

     // 指定镜面指数
     glMateriali(GL_FRONT, GL_SHININESS, 128);

     GL_SHININESS属性设置材料的镜面指数。镜面指数指定了镜面加亮的大小范围和集中性。如果它的值是0,表示未聚焦的镜面加亮,实际上就是整个多边形的颜色均匀加亮。如果这个值大于0,就可以缩小镜面加亮的范围,同时增加镜面加亮的集中程度,从而出现亮点的效果。它的值越大,亮点就越明显。在所有的OpenGL实现中,这个参数的范围是1至128.

 OpenGL中设置光照的镜面反射效果     OpenGL中设置光照的镜面反射效果
           镜面指数为0,均匀加亮                         镜面指数为128,局部加亮

     这一部分的示例程序完整代码已经放到了GitHub上,有需要的朋友可以参考一下(https://github.com/dxm3dp/OpenGL-05-LITJET点击打开链接)。


     
     本文出自杜晓萌的博客,请勿用于任何商业用途,转载请保持完整性并标明出处:http://blog.csdn.net/haohan_meng