OpenGL超级宝典笔记——现实中的颜色与材料


现实中的颜色

如下图:我们为物体构造好了模型,也为每个平面设置了颜色值,但最终画出来的物体却一点都不像真实世界中的物体。在真实世界中物体的表面最终呈现的颜色还取决于你观察它的角度以及光源。

image

OpenGL提供了近似于真实世界的光照环境。在OpenGl中物体会被三种光照射:环境光,漫放射光,镜面光。通过调整这三种光源的属性,我们可以使得物体看起来更真实。

 

环境光

环境光没有特定的方向。环境光的光线充满着整个场景。场景中的物体都被环境光从各个方向照射着。环境光的特点是:照射在物体上的光来自周围各个方向,又均匀地向各个方向反射。

image

 

漫反射光

漫放射光是一组来自特定方向,具有方向性的光。根据入射光线的角度在表面上均匀地向各个方向反射。漫反射的特点是:光源来自一个方向,反射光均匀地射向各个方向。漫反射光采用点光源照射物体。点光源是位于空间某个位置的一个点,向周围所有的方向上辐射等光强的光。在点光源的照射下,物体表面的不同部分亮度不同,亮度的大小依赖于它的朝向以及它与点光源之间的距离。

image

 

镜面光

镜面光与漫反射光一样是具有方向性的。高强度的镜面光会在被照射的物体的表面上形成亮点。对于理想的高光泽度反射面,反射角等于入射角时,光线才会被反射,即只有在等于入射角的反射角方向上,观察者才能看到反射光。对于这种理想的反射面,镜面反射的光强要比环境光和漫反射的光强高出很多倍,这时,如果观察者正好处在P点的镜面反射方向上,就会看到一个比周围亮得多的高光点。

 

image

 

综合影响

事实上,光源是由各种强度不同的类型的光组成的。场景中的光源是由3种光组成的:环境光,漫反射光,镜面光。每种光的成分也像颜色一样是由RGBA值定义的。它描述了组成这种成分的红光,绿光,蓝光的强度(对于光的颜色而言,alpha值被忽略)。

红色射线的光源成分分布:

image

红色射线不包含绿光和蓝光成分。这些光源成分的强度取值范围在0.0到1.0之间。上面的表格说明了红色射线包含非常高的镜面光的成分,一点漫放射光成分,和非常少的环境光成分。(注:镜面光的强度要大于其他成分才可能产生亮点).在被红色光照射的地方你可能(取决于观察点是否在光反射的方向上)会看到一个很亮的红点。

 

现实世界的材料

材料的颜色是根据它所放射的光的波长来定义的。一个蓝色的球体反射了绝大部分的蓝色光子且吸收了其他颜色的光子。在现实世界中白光包含了所有颜色的光,所以我们能够看到材料它本身的颜色。如果蓝色的球体在单纯的红光照射下,我们看到的将是黑色的。

 

材料的属性

当我们使用光照时,我们是通过材料的反射属性来描述它的颜色的。我们会说一个多边形反射了绝大多数的红光,而不会说这个多边形是红色的。我们为三种光源:环境光,漫放射光,镜面光,指定材料相应的反射属性。一个材料可能会很好的反射镜面光,却吸收了大多数的漫放射光和环境光。

 

给材料添加光照

物体有它自己反射的颜色,光源也有它自己的颜色。OpenGL是如何决定使用哪种颜色的?

 

环境光的效果

若光源颜色为( LR , LG , LB ),材质颜色为( MR , MG , MB ),最终颜色为( LR*MR , LG*MG , LB*MB )。(B1+B2)*MB )。因此,材料的颜色成分决定了入射光被反射的百分比。例子:

光源颜色为(0.5, 0.5, 0.5), 材料的颜色为(0.5, 1.0, 0.5)那么最终的颜色是

(0.5*0.5, 0.5*1.0, 0.5*0.5) = (0.25, 0.5, 0.25) 。

公式

ambient = Ka x globalAmbient

image

 

漫反射光与镜面光的效果

漫反射光具有方向性,而且照射在物体表面上光的强度与光源和表面的夹角、光源和表面的距离以及相关的衰减因素有关(在光源和物体之间是否有雾)。

反射光的计算通常用Lambert定律:

Ildiff = Kd * Il * Cos(θ)
其中Il是点光源强度,θ是入射光方向与顶点法线的夹角,称入射角(0<=A<=90°),Ildiff是漫反射体与方向光交互反射的光强,若 N为顶点单位法向量,L表示从顶点指向光源的单位向量(注意顶点指向光源),则Cos(θ)等价于dot(N,L),故又有:
Ildiff = Kd * Il * dot(N,L)

镜面光的计算方法比较复杂。最常用的计算方法是:先通过光线的方向向量和物体的平面法向量来计算出光线的反射方向向量。然后再用光线的反射方向向量和视线的方向向量做点积来计算出光线对眼睛的作用强度。再把这个计算得到的作用强度以光泽度值作乘方运算来增加高光部分的汇聚性,减少扩散。最后再把计算结果乘上光线本身的颜色。

冯氏模型公式如下:

spec = Ks * Il * ( dot(V,R) )^Ns
其中Ks 为镜面反射系数,Ns是高光指数,V表示从顶点到视点的观察方向,R代表反射光方向。由于反射光的方向R可以通过入射光方向L(从顶点指向光源)和物体的法向量求出,
R + L = 2 * dot(N, L) * N  即 R = 2 * dot(N,L) * N - L
所以最终的计算式为:
Ispec = Ks * Il * ( dot(V, (2 * dot(N,L) * N – L ) )^Ns

OpenGL超级宝典 第4版 中文版PDF+英文版+源代码 见 

OpenGL编程指南(原书第7版)中文扫描版PDF 下载

OpenGL 渲染篇

Ubuntu 13.04 安装 OpenGL

OpenGL三维球体数据生成与绘制【附源码】

Ubuntu下OpenGL编程基础解析

如何在Ubuntu使用eclipse for c++配置OpenGL  

更多《OpenGL超级宝典学习笔记》相关知识 见 

相关内容