更新于 

光照原理

光线照射时需要注意的两个重要的现象
  • 物体不同表面的 明暗程度 变得不一致
  • 物体向地面投下了 影子
着色器与光照
  • 着色(shading) 真正的含义就是: 根据光照条件重建物体各表面明暗不一的效果
  • 着色器(Shader) 最初被发明出来就是为了: 重建光照产生的明暗现象
着色过程需要重点考虑的两点:
  • 发出光线的 光源类型
  • 物体表面 如何反射光线

光源类型

三种基本光源类型
类型描述定义条件类比
平行光(directional light)光线相互平行,可以看做无限远处光源发出的光方向,颜色太阳光
点光源光(point light)从一个点向周围所有方向发出的光位置,颜色灯泡、火焰
环境光(ambient light)从各个角度照射物体,强度一致颜色打开冰箱门的灯光

反射类型

影响反射光的2个因素是什么?

答: 入射光和物体表面的类型。

入射光物体表面
方向基底色
颜色反射特性
物体表面反射光线的方式(2种)
  • 漫反射 diffuse reflection
  • 环境反射 enviroment ambient reflection

漫反射是针对平行光或点光源的。

反射方向

漫反射反射光 在各个方向上是均匀的
一般针对表面粗糙的材质,是一种理想的反射模型。

反射颜色

反射颜色受三个因素的影响:

  • 入射光的颜色
  • 表面的基底色
  • 入射角 入射光与表面发现形成的夹角θ

漫反射光颜色的计算公式:

1
<漫反射光颜色> = <入射光颜色> * <表面基底色> * cosθ 

环境反射是针对环境光的。

反射方向

反射光方向可以认为就是 入射光的反方向

反射颜色
1
<环境反射光颜色> = <入射光颜色> * <表面基底色>
漫反射和环境反射同时存在时的颜色计算公式
1
<表面的反射光颜色> = <漫反射光颜色> + <环境反射光颜色>

入射角的计算

矢量点积

如果要对 矢量n矢量l 做点积运算,公式如下:

1
n·l = |n| * |l| * cosθ

由此可以推演出入射角cosθ的计算公式:

1
cosθ = n·l/(|n| * |l|)

GLSL_ES中内置了点积运算函数,可以直接使用·表示点积运算。

1
cosθ = <光线方向> · <法线方向> 
内置函数计算点积实际用到的公式
  • n = ( nx, ny, nz )
  • l = ( lx, ly, lz )
    1
    n·l = nx*lx + ny*ly + nz*lz
使用点积表示的漫反射光颜色公式
1
<漫反射光颜色> = <入射光颜色> * <表面基底色> * (<光线方向> · <法线方向>)
注意点1:参与计算的矢量需要进行归一化处理。

光线方向矢量表面法线矢量 长度必须是1,
否则反射光颜色就会过暗或过亮。

归一化(normalization)

指的是将一个矢量 长度调整为1,同时保持方向不变。

假设矢量n = (nx,ny,nz)
设矢量n的长度为m,即 |n|= m = sqrt(nx^2 + ny^2 + nz^2)
n归一化后结果为 (nx/m,ny/m,nz/m)
如设n = (2.0,2.0,1.0)
|n| = sqrt(2^2 + 2^2 + 1^2) = 3
n归一化结果 = (2.0/3, 2.0/3, 1.0/3)

注意点2:光线方向到底是指向哪里?

答: 实际上是入射方向的反方向。

法线

法线是什么?

法线法向量,表示物体表面的朝向,即垂直于表面的方向。
法向量的相关问题需要考虑下面两点:

注意点1:一个表面具有两个法向量

就好像奥利奥的夹心两边都有饼干一样。

xy平面 的两个法向量分别是:

  • (0,0,1)
  • (0,0,-1)
注意点2:平面的法向量唯一

法向量表示的是 方向,和位置无关,因此:

  • 同一平面的任意一点都有相同的法向量

    法向量只表示方向,与位置无关
    法向量只表示方向,与位置无关
  • 朝向相同的个不同平面的法向量也相同
    就像同一根签穿起来的糖葫芦球一样。

法向量的写入

计算好的法向量和其他attribute类型的属性一样,也需要传给顶点着色器程序,
其操作方法类似于 ColoredCube颜色缓冲区 的写入。
如立方体的每个顶点对应3个法向量(这是由于立方体表面垂直相交的缘故,但是表面光滑的物体通常每个顶点只对应1个法向量)。