三维模型中的每一个三角形都有一个面朝方向(facing direction),顾名思义指的是三角形的朝向。这个方向通常用一个从三角形中心出发垂直于三角形表面的箭头表示。面朝方向对于光线在物体表面反射的时候起到了至关重要的作用。如果两个相隔很近的三角形朝向不同,它们就会将照射光反射到不同的角度上,因此这两个三角形的着色方式会大不一样。对于弧形物体就有点麻烦了,因为弧形表面没法用平的三角形拼凑出来。为了避免这个问题,在处理弧形表面的光照效果时,我们忽略其朝向,而是使用其法线方向(normal direction)。在2.4节中已经提到过了,顶点可以储存数据。在顶点所保存的数据中,法线方向是仅次于UV值的一个非常重要的参数。法线方向是一个单位长度的向量,表示顶点面朝的方向。与面朝方向不同的是,三角形中的每一个点都有其独有的法线方向,它们的法线方向是基于顶点的法线方向通过线性插值得到的。通过这种方式,我们可以用一些低精度模型制作出高精度的几何体。下图展示了一个相同的几何体在使用不同的顶点法线时的渲染效果。最左边这个图像中,法线完全垂直于三个顶点围城的平面,可以看出每个面之间有清晰的分界,而最右侧的图像中法线是在整个表面进行插值计算得到的,通过这种方式哪怕物体表面是粗糙的,也可以让它看起来很光滑。通过下图很容易看出来,即便是三个一模一样的几何体,它们在光照下的反射情况也大不一样。尽管最右边这个图像中的几何体也是用平面三角形围成的,但是看起来就好像它是一个完美的球面一样。
使用顶点法线插值得到的物体都有一个普遍的特点:表面看着很光滑,但是边缘却很尖锐。这一点可以通过标注出每一个顶点保存的法线方向看出来,如下图所示。你可以发现虽然每一个三角形都只有三个法线,但是大部分三角形放在一起的时候,某些相邻的顶点的法线方向是一样的,这也是为什么右边这个图像中的法线数量较少的原因,因为很多顶点的法线都重合了。 计算三维模型的法线原本是一项技术,但是迅速让位给另外一种更高级的技术,即法线映射。与纹理映射差不多,法线方向可以通过一个额外的纹理来提供。这个额外的纹理通常称为法线映射或者bump映射。法线映射通常是一些RGB图像,RGB的成分值分别用来表示法线方向(X, Y, Z)的值。有很多方式可以创建法线映射。某些应用程序,比如CrazyBump( http://www.crazybump. com/ )或者NDO Painter( http://quixel.se/ndo/),可以接受一个二维数据然后将其转化为你想要的法线数据。其他一些应用程序,比如Zbrush 4R7( http://www.pixologic. com/)和AUTODESK( http://usa.autodesk.com),可以接受一个三维雕刻数据,然后创建一些法线映射。创建法线映射的步骤完全超出了本书的范围,但是上面提到的这些链接或许会给你提供些许帮助。 在Unity中给表面着色器添加法线映射的过程非常简单,只需要使用UnpackNormals()函数就可以了,我们接下来看看应该怎么做。 2.6.1 准备工作 创建一个新的材质和着色器,然后启动一个新的项目,将新的着色器和材质放置到Scen视图中。这样我们就可以得到一个干净的工作空间,接下来可以看看法线映射技术。 这一节需要一个法线映射,如果没有的话在本书附带的Unity项目中有一个。 本书中附带的法线映射示例如下图所示: 2.6.2 操作步骤 下面是创建法线映射着色器的详细步骤:通过将纹理初始化为bump,告诉Unity _NormalTex会包含一个法线映射。如果没有设置纹理,则会使用一个灰度纹理替代。这里用的(0.5,0.5,0.5,1)颜色用来表示一点bump都没有。