- 注意!本文是在下几年前入门期间所写(young and naive),其中许多表述可能不正确,为防止误导,请各位读者仔细鉴别。
最基础的几种光照原理及实现
法线变换
由于要实现光照了,法线也要变换到世界坐标里来做运算,但是法线是不能直接乘一个world矩阵来变换的,因为如果这个world矩阵包含了各向不统一的缩放,法线就不会再垂直于表面了。
如图,我们要的是c而不是b,如果要变换后依然垂直,应该不是直接乘世界矩阵,而是乘世界矩阵的逆转置。而且有一点要注意的是,逆转置矩阵不能随便乘其他矩阵,除非把矩阵里的translation成分剔除掉,因为本来我们把向量的第四维设置成0,就是为了translation不会影响向量,只会影响点,translation在第四行,但是如果逆转置了,translation就被翻上来了,翻上来不要紧,只要规定向量第四维是0还是不会有影响,但是如果要和别的矩阵乘的话,第四列里的translation就会“泄露”到其他矩阵里去,影响结果,所以之后我们处理法向量的时候应该只要world矩阵的前3x3和法向量的前三维,即把translation剔除掉。
兰伯特光照
有两个概念可以了解一下,radiant flux辐射通量,即每秒通过的能量,irradiance辐射照度,即每秒通过单位面积的能量值。这里说的兰伯特只是指漫反射和高光部分遵循兰伯特余弦定理,实际上还有个环境光我们考虑各向强度完全相同,也就不考虑角度了。
漫反射我们认为各个角度都相同,而高光的话则要考虑菲涅尔和粗糙度的影响。
Fresnel效应的Schlick近似:
其中0度的RF我们在材质里定义。
然后还有个光滑程度的影响
这个m是光滑度,越大越光滑,在我们这个demo中,材质的shininess等于1-roughness,而m=256*shininess。然后h向量是把入射光方向L和toEye向量对半分的中间向量,即halfVec。m越大反光位置越集中,不同m的粗糙度因数曲线如下
然后最终的光照结果可以由下式求得
A L A_{L} AL是环境光的rgb, m d m_{d} md是材质的albedo,L是点到光源的单位向量,n是法线, B L B_{L} BL是光照rgb,故括号外面这个是考虑了兰伯特余弦的光照rgb,然后括号里面 m d m_{d} md的部分是漫反射,高光则是乘了菲涅尔的因数和粗糙度的因数,其中h是half vector, α h \alpha_{h} αh则是h和L的夹角, R F ( α h ) R_{F}(\alpha_{h}) RF(αh)是已知 R F ( 0 ∘ ) R_{F}(0^\circ) RF(0∘)的情况下算出来的菲涅尔因数,