14.2. 经验光照模型#

14.2.1. 冯反射模型#

14.2.2. 布林—冯反射模型#

14.2.3. 着色频率#

在给定光照、物体几何和材质之后,决定像素颜色最关键的就是表面的法向。第一种着色方法就是使用三角形的面法向,逐三角形确定颜色,这种着色方法称为平面着色(Flat Shading),如图 14.1 所示。

../../_images/rendering-shading-flat.png

图 14.1 平面着色的效果。图片来源于维基百科。#

在平面着色中,每个三角形只有一个法向,每个三角形只有一个颜色,于是我们能在渲染结果里看到很多独立的面片,但是我们还是可以直观看到整个形状上明暗的过渡以及高光。如果我们的三角面片足够多,我们就能得到一个光滑的表面,但是如何在三角形数量不够的时候依然让表面看起来光滑呢?这就引入了第二种着色方法:计算每个顶点的颜色,然后在三角形中间插值。这种着色方法称为高洛德着色(Gouraud Shading),是由法裔计算机科学家亨利·高洛德(Henri Gouraud)在 1971 年提出的[Gou71],结果如图 14.2 所示。

../../_images/rendering-shading-gouraud.png

图 14.2 高洛德着色的效果。图片来源于维基百科。#

高洛德着色中,我们不再是逐三角形着色,而是逐顶点着色。我们使用每个顶点的顶点法向计算光照颜色,然后在三角形内部用重心坐标进行插值。从结果可以看到,在曲面的大部分区域里我们得到了光滑的颜色过渡,但是在高光区域我们能明显看到三角形插值的痕迹。同样,如果我们增加三角形的数量,我们依然能够得到光滑的渲染结果,但是有没有方法能够在当前的精度下进一步减小离散化带来的误差?我们首先思考一下顶点颜色插值的合理性。如果三角形近似的曲面正对着光源方向,那么三角形中心的高光应该要强于顶点处的高光,这表明三角形中心的颜色并不能写成顶点颜色的线性插值,因为插值出来的亮度不可能强于被插值的顶点的亮度。因此对颜色插值并不是一个好的策略,我们需要考虑三角形内部颜色随位置的非线性变化。既然不能通过插值得到颜色,我们就只有对三角形上的每一个点都计算一个颜色,这样我们的着色方案就不再是逐顶点的,而是逐像素的。这种着色方法称为冯着色(Phong Shading),由美国越南裔学者裴祥风(Bui Tuong Phong)在 1975 年提出的[Pho75],如图 14.3 所示。注意这里的冯着色模型不同于前面的布林—冯反射模型,前者描述的是着色方法,后者描述的是光照模型。

../../_images/rendering-shading-phong.png

图 14.3 冯着色的效果。图片来源于维基百科。#

在冯着色中我们需要单独计算每个像素的颜色,也就需要每个像素的法向。像素的法向与深度一样,需要在透视投影之前插值才能得到正确结果,因此我们需要使用公式???进行透视矫正的重心坐标插值,同时在插值之后还需要归一化。从图 14.3 可以看出,冯着色能够正确画出椭圆形的高光区域,不再有高洛德着色的不自然高光了。

从平面着色到冯着色,我们发现我们需要计算的颜色数量在增加,从逐三角形到逐顶点再到逐像素,换句话说就是着色频率(shading frequency)在增加,效果也在逐渐接近真实。由于冯着色需要对每个三角形的每个像素计算光照,因此公式???和公式???会被频繁调用,这也是我们如此强调它们的计算效率的原因。