本文已参与[新人创作礼]活动,一起开启掘金创作之路
转载请注明出处.
图形学的数学基础(二十九):着色(下)
高光(SpecularReflection)
让我们从反射开始,反射是光与物质相互作用的一种形式。反射是光子或入射光束撞击到反射表面的结果,例如玻璃,光滑的金属,镜子都容易形成高光反射。反弹的方向与撞击点表面法线方向对称,也就是说,如果入射方向与表面法线的夹角记为θi,反射方向与表面法线的夹角为θr,则θi=θr。这就是的反射定律。因此当观测方向与反射方向接近时,高光表现强烈,反之高光表现减弱,高光项与反射矢量和观测矢量的点积成正比。因此高光是与观测方向紧密相关的。

计算反射向量
接下来需要计算反射向量,然后通过反射向量和观测向量做点积,即可得到从当前视角观测着色点的高光分量。那么如何计算反射向量呢?可以线计算L^在n^上的投影向量B(向量点积即可),然后根据向量加法计算A向量。如下:

B=cosθi∣∣L∣∣n^=(L^⋅n^)n^2A=B−L^=(L^⋅n^)n^−LR=B+2A=(L^⋅n^)n^+(L^⋅n^)n^−L=2(L^⋅n^)n^−L^
半程向量(halfvector)
但是以上计算反射向量的方法过去繁琐,有一种更加简便的办法,通过半程向量(光照方向和观测方向的角平分线方向,利用向量平行四边形法则求和然后归一化处理即可)。半程向量与法线方向越接近,则观测方向与反射方向就越接近。因此可以计算半程向量和法线的点积来代替反射方向与观测方向的点积,因为半程向量好计算(只需要加法操作),省去了一次向量点积带来运算开销。

h^=bisector(v, l)=∣∣l^∣∣+∣∣v^∣∣l^+v^
高光计算公式

- Ks(镜面反射系数):系数越大,亮度越大。同时因为高光通常是白色,所以表示颜色通常也为白色。
- r2E: 布林冯为经验模型,用抵达着色点的能量近似代替被着色点接收的能量,因此此处并没有像漫反射一样计算夹角余弦。
- bisector: 布林冯模型对冯模型的改进,用半程向量代替反射向量,减少了一次点乘计算。
- 指数P:最后带有一个指数p,该指数用于加快函数的衰减程度,由于在物理世界中高光存在于物体表面很小的一部分,而的衰减速度太慢,通过携带指数,可以促进衰减速度,使得高光只能在与法线向量非常接近的情况下才能被视角看见.


环境光(Ambient)
在 Blinn-Phong 模型中,举出了一个非常大胆的假设:物体表面接收到的各种环境光都是相同强度的。当然,这并不符合常理,但是可以大大简化了计算环境光的步骤,强度相同,意味着反射光的强度也相同,而由于环境光来自四面八方的物体反射,所以该物体表面反射环境光的方向也是四面八方的,那么:环境光与光源的角度无关,与观察角度也无关,所以它是一个常数。
计算环境光的公式非常简单,只需要得到物体表面的环境光吸收率和环境光的强度即可:
La=KaEa
总结blinn−PhongReflectanceModel
最后,将漫反射光、高光和环境光作用在物体表面上的效果叠加在一起,就可以得到近似于物理光照的效果。

L=La+Ld+Ls=KaEa+Kdr2Emax(0,n^⋅l^)+Ksr2Emax(0,n^⋅h^)p
参考
GAMES101 -现代计算机图形学入门-闫令琪