zoukankan      html  css  js  c++  java
  • SharpGL学习笔记(九) OpenGL的光照模型, 术语解释

    在3D场景中,每个像素最终显示出来的颜色都是经过大量计算而得到的,其中一些计算是依赖于场景中的光照以及场景中物体对光线的反射和吸收情况.

    例如,对于一个红色的物体, 在白色光(白光是红光,绿光和蓝光等量的光) 的照射下它是红色的, 而在绿色光的照射下它将显示为黑色.

    如果场景不存在光源效果,那么就没有了3D效果。 下图左边是有光照的效果, 右图是没有光照的效果.

    (一)OpenGL的光照模型


    OpenGL的光, 可以分解为红,绿,蓝3种分量. 对于光源来说, 使用其发射的红,绿,蓝光的量来描述.
    对于物体表面的材质则可以使用其在各个方向反射的红,绿,蓝光的比例来描述.

    OpenGL的光照模型将光照分为4个独立的部分:
    环境光(ambient light)
    漫射光(diffuse light)
    镜面反射光(specular light)
    发射光(emitted light)
    这4种光分别计算,然后被叠加起来.

    下面来张示意图, 它比较好的解释了其中3种光照效果组成部分。

    环境光(ambient light)

    环境光是场景中的基本光源。如果你进入一个漆黑的屋子,环境光通常是零,但走到外面时,总是有光能让你看到。环境光没有方向(所以也将其称为“全局光照模型”).

    在室内, 环境通常是经环境散射无法确定方向的光, 就好像来自四面八方的光.

    漫射光(diffuse light)
    实际看看周围的桌面,墙面,太阳照射到上面的时候,我们就能看到光,大多数情况下,我们看到的多数光源是漫射光传播到我们的眼睛。

    就像下图这样子:

    我们平时看到的桌面或者墙壁都是平滑的,那么也就是说n法线都应该是垂直向上才对,也就是说光的反射不一定能传播进我们的眼睛了?那为什么我们从不同角度看这个桌面,它的漫射光都是一样的呢?

    解决这个问题的关键就是:在微观条件下表面都是粗糙的。

    就是如果我们使用显微镜观察一个很平滑的桌面,也会发现是凹凸不平的。凹凸不平到什么程度呢?从所有不同方向和角度都能观察到其粗糙程度是一样的。这么思考之后,就可以想通了,微观法线并不是垂直向上的,而是在不同角度。

    镜面反射光(specular light)

    就是平时我们看到的一个光滑球面会发出的耀眼光点。如下图:

    金属表面,塑料,玻璃,瓶子等容易观察到这种镜面反射光.

    关于镜面反射光的几点说明:

    1 球面容易看到镜面反射光,是因为球面的法线向外扩散,让看到高亮光的区域更大,那么就更加容易看到镜面反射光了。

    2 镜面表面很平滑,那么镜面反射光就会很集中,虽然看到的区域小,但是因为高亮的强度很大,那么就可以很清晰的看到镜面反射光了。

    3 其实镜面反射光可以发生在任何物体和任何表面上。

    4 粗糙的表面镜面反射光效果很弱或者甚至看不到镜面反射光

     发射光(emitted light)

    这种光是一种材质发出来的光,用来模拟物体发出来的光, 在3dsmax中,被称为自发光材质. 

    比如一个场景中有个白炽灯泡, 那么这个为这个灯泡就可以赋上"自发光材质"

     下图是3dsmax的光照渲染出来的效果, 按上面的理论, 它应该是由以上四种光源类型叠加出来的.

    笔者来给大家分离单独的光源类型, 看看实际效果是什么样子.

    首先, 环境光(ambient light) , 这个场景是开放的不是室内, 因此我们就不管环境光了.

    然后, 发射光(emitted light), 在下面场景中是不存在的. 我们也不管.

    我们只研究一下下面场景中的,  漫射光(diffuse light), 镜面反射光(specular light) 是个什么样子.

     下面是被分离出来的 漫射光(diffuse light)

     

     下面是被分离出来的 镜面反射光(specular light) 

    因此,这个场景中的光照,就是由上面两张图片所示的 漫射光(diffuse light), 镜面反射光(specular light) 构成的。

    (二)法线向量

    法线向量简称法线。是垂直于表面的向量。对于一个平面, 所有顶点的法线都是一样的。 对于曲面,各个顶点的法线方向可能不同。

    笔者当初学习3dsmax的时候,总不知道法线是什么,后来学会了3dsmax的法线对齐功能的用法,突然就明白了法线是什么了。

    这个法线对齐要求先在要被对齐的对象(下图是长方体) 的某个面点一下, 系统确定了这个面的法线, 在下图是长方体顶面上的蓝线。

    然后再去要对齐到的对象的那个面上点一下,系统又确定了那个面的法线, 在下图是球面上那根亮绿色的线。

     然后,两个面就按法线相向的姿式对到一齐去了。

     

    不用搬出公式,也不用废话,你明白了吗?

    法线在3dsmax里面还决定了某个面是否可见, 法线正方向的面你的眼睛可见, 法线反方向的面,你的眼睛就看不见这个面了。

    如下面左图是球体法线正方向对着你的眼睛, 所以其面都可见。 而右图是球体的法线的正方向在在球的背面,对着你眼睛的是法线反方向,因此前面的面消失了,看到了球内部。

          

    而在OpenGL中,OpenGL是使用法线向量来确定一个物体表面的某个顶点所接受的光照的。如果不想使用OpenGL的光照功能,就可以免去为顶点指定法线向量这个步骤的。

    原创文章,出自"博客园, 猪悟能'S博客" : http://www.cnblogs.com/hackpig/

  • 相关阅读:
    二级菜单
    侧面导航
    QFileDialog文件保存
    GitHub for window
    Qt学习事件/信号
    开始RTThread之旅
    Qt事件过滤器
    LPC1768开发板液晶问题解决
    用QSplitter分裂器实现QTextEdit窗口大小的变化
    Qt之串口编程使用事件驱动来触发接收数据
  • 原文地址:https://www.cnblogs.com/hackpig/p/5799804.html
Copyright © 2011-2022 走看看