万物皆有菲涅耳fresnel
当今游戏里面高光照明已成标准,然而游戏中少见的是正确的菲涅耳(fresnel)效果。希望现在你知道什么是高光(specular)了。电脑游戏里面最常见的高光模型是Blinn-Phong也就是:

H = normalize(V+L);
specVal = pow(saturate(dot(H,N)),power);
在本例中, V就是观察者的向量, L是光线的向量, N是法线向量。power是高光的指数, H是衍生半向量(derived half vector),也就是介于观察者与光线中间的向量。怎样运作的呢?以下是图解。你可以看到观察者、光线与法线向量。现在,有了这个函数高光的峰值在哪里呢?直觉上,你可能希望高光函数达到最高当观察者向量等于光线的反射向量,结果也是如此,这个函数达到峰值当半向量正好对齐法线,刚好等于反射的观察者向量点正好在光线上,一切都合理。
另一种状况:

再次,观察者向量正反应了光线向量。本例中,高光的亮点会更亮?更暗?或是跟第一个例子一模一样?嗯,应该是一样,因为在两个例子中,你都是直接观察高光亮点的最大值,真实世界是这样运作的吗?简单的说,不是。
这是一张砖头的照片,从不同的摄影机角度。上面那张,灯光与摄影机都是直接朝下,类似于第一个状况。第二张照片,光线是以掠射角的角度撞击表面,类似于第二个例子。我把高光与漫射以偏光镜分开,因此漫射在左边,高光在右边,让我们来仔细瞧瞧。

所以...我靠!如同像砖头这样简单的材质Blinn-Phong的shading模型竟然高光完全错误, 结果是因为某个叫做fresnel的小玩意。我们再来看两个高光的例子。根据Blinn-Phong 这两个应该会有相同的强度,但是实际上,其中一个在掠射角的角度结果亮很多。

把这个效应考虑进去,你可以使用Fresnel。即时的Fresnel可以用Schlick Fresnel概略地得出,以下从the GPU Gems 3 chapter on skin书中的章节得到:
float base = 1 - dot(V,H);
float exponential = pow( base, 5.0);
float fresnel = exponential + F0 * (1.0 - exponential);
specVal *= fresnel;
因为某些原因,大部分的人希望fresnel只发生在反光强的表面,例如水、玻璃与金属。事实上fresnel的效应在几乎所有的材质都很强。事实上,我认为fresnel在哪些反光弱的材质,视觉上更加重要。以下是PVC水管:

很显然PVC具有fresnel效应,但是依我之见,我会说砖头上的fresnel效应会比PVC 视觉上更为重要!从完全没有到非常强的高光会比,强的高光到更高的高光更为重要。难道这不是更为重要的视觉效果吗?我认为,以为fresnel只发生在水/玻璃/金属是种错误的想法,因为对于反光弱的表面fresnel的视觉效果差异更加明显。以下有更多例子:

可怜的纸板,被大家都误解了!通常纸板大家都认为是完全的漫射材质,就算它值得跟其他的亮亮材质朋友一起出场。高光在直视的角度很重要,因为会添加细微的去饱和度效果。但是纸板在掠射角具有非常高的高光反射。

你曾想过为何在早上开车上班会感觉比较亮吗?大部分人以为这是太阳照射到眼睛的关系,事实上,路面强大的fresnel效应是主要亮度增加的来源。下次阳光直射眼睛的时候, 请留意汽车后照镜的路面比正面的路面要暗许多。

这里有些衣服,是IKEA买的。粗糙、棉质的衣服具有很少的高光。这样比较并不是很好的例子,因为第二张图整体来说更亮,这样你很难看出高光到漫射的改变。如果你想要有更好的例子,那就当作各位读者的回家作业吧!

好玩一下,让我们来看一下X-Rite色温版。当你使用彩色的色温版,建议你要垂直于摄影机,应该不需要跟你说为什么吧?!