OpenGL 光照

前言

光照射到物体表面,经过反射到达人眼,使得人们可以看清楚这花花世界。实际上,在计算机中模拟自然光是不现实的,大多数情况下,实现光照效果使用的是光照模型。现在最常见的光照模型被称为“ADS”模型。

光照模型

所谓“ADS”模型,是将光照到物体表面所产生的反射分为三类:环境光反射,漫反射和镜面反射。

  • 环境光反射:影响场景中所有的物体
  • 漫反射:根据光的入射角度调整物体的亮度
  • 镜面反射:展示物体的光泽

镜面反射在光照射到光滑表面上发生,且只能在特定角度观察到;而漫反射在光照射到粗糙表面上发生,可以在各个角度观察到。

场景的绘制最终是由片段着色器为屏幕上每个像素输出颜色实现。因此需要计算像素的RGBA输出值上的光照产生的分量。需要计算的因素包括:

  • 光源类型及其环境、漫反射和镜面反射特性;
  • 物体材质的环境、漫反射和镜面反射特征以及物体材质的光泽度;
  • 光源照射物体的角度;
  • 观察视线到物体的角度。

光照计算

在绘制场景时,模型顶点的坐标经过OpenGL渲染管线从3D变换到2D屏幕上。2D屏幕中模型的每个像素颜色都是经过光栅化、贴图以及插值的结果。而ADS模型就是调整光栅化后的像素颜色,以便反映出场景中的光照以及模型的材质。
每个像素的反射强度如下计算:
Iobserved=Iambient+Idiffuse+IspecularI_{observed}=I_{ambient}+I_{diffuse}+I_{specular}

  1. 环境光强度的计算最简单,直接将光源的环境光分量乘以材质的环境光分量即可。
  2. 漫反射分量需要考虑光的入射角,根据朗伯余弦定理,漫反射分量是光源的漫反射分量乘以材质的漫反射分量再乘以入射角的余弦值。
  3. 漫反射分量则要考虑观察向量和光线反射向量之间的夹角。

实现ADS光照

上述计算是理论上的,因为它假设我们能对每个像素执行操作。然而实际上,大多是场景模型的像素是通过顶点插值得到的,且只有顶点才具有法向量。这使得计算很不方便,因此需要有一些方法来估计所需要的值以实现比较好的光照效果。
比较流行的着色方法是Ground着色和Phong着色。前者按照顶点进行计算而后者按照像素进行计算。如图所示:

OpenGL 光照1. Ground OpenGL 光照2. Phong

啧啧,这HTML语法用的还是不溜啊
感觉这两种实现的效果并没有多大差别,可能是用的模型太简单了吧,之后用更复杂的模型再研究研究。