法线贴图
法线贴图 3D模型的每一个三角面都有一个 朝向facing direction ,这个朝向就是它向前的指向。它通常用一个垂直并且放置在三角面正中心的一个箭头来表示。这个朝向对于光在表面反射中来说非常的重要。如果相邻的两个三角面朝向不同的方向,那么它们对光的反射也会朝向不同的角度,也就是在着色器中它们的处理方式会不一样。对于曲面物体来说,这里有个疑问:很显然这些拥有曲面的几何体仍然是由平面三角形构成的,那光线改如何处理? 为了避免这个问题,对应三角面的光的反射计算方式此时不根据它的朝向计算,而是根据它的 法线方向normal direction 方向计算。前面 向着色器添加纹理 那个知识点讲到,顶点是保存有数据的。法线方向信息也是继UV信息之后,保存在顶点中最有用的信息。这是一个单位长度的向量,并且它表示了顶点的朝向。不考虑朝向的话,那么三角面内的每一个顶点都有它自己的法线方向,只不过这个法线方向是一个存储在顶点中的线性插值。这给了我们用低模模拟高模的能力。下面示例图展示了同一个几何形状在不同的顶点插值密度下的表现。在左边,法线垂直于由顶点表示的面;很明显每个面之间有明显的的割裂感。再看看最右边的几何体,它的法线是通过他的面线性插值得到的,可以看出来的是,尽管它的表面看起来还是很粗糙,但是光线的反射看起来却似乎很光滑。很容易看出来尽管这三个物体的几何体都相同,但是它们的光线反射却不一样。尽管都是由平面三角形构成,但是右边物体的光线反射似乎看起来像曲面反射。 一个有着粗糙的边的光滑物体很明显的表示单位顶点的法线肯定进行了线性插值。如果我们对保存在每个顶点的法线按其方向进行绘制,我们就能够看到它们,正如下图所展示的那样。你应该注意的是每个三角形仅有三条法线,但是相连的三角形有相同的顶点,会看到不止有一条法线从中绘制出来。 法线贴图在计算3D模型的法线技术中脱颖而出。跟纹理贴图类似,法线方向也可以用一张额外的纹理表示,我们把它们叫做 法线贴图normal map 或者 凹凸贴图bump map 。 法线贴图通常是一张RGB图片,里面的RGB通常分别用来表示法线方向中的X,Y,Z方向。现在有很多种技术方法来创建一张法线贴图。比如这些应用程序,CrazyBump (http://www.crazybump.com/)跟 NDO Painter (http://www.crazybump.com/)可以把2D数据转换成法线数据。其他的应用程序比如 Zbrush 4R7 (http://www.pixologic.com/)和 AUTODESK (http://usa.autodesk.com)可以把雕刻数据转换成法线贴图。如何创建法线贴图完全超出了本书的范畴,但上面的内容对你了解相关相应的知识还是有好处的。 在Unity中向着色器添加法线的过程很简单,因为在表面着色器中有着 UnpackNormals() 这样的方法给你调用。就让我们看看这是怎样的一个过程。 始前准备 分别创建一个新的材质和着色器,并且把它设置到 场景视图Scene view 中的游戏对象中去。这样的话,我们的项目非常简单,好让我们仅仅是观察法线贴图这项技术。 这个知识点中你需要一张法线贴图,但是我们这本书附带的Unity工程中包含了一张。[当然,你也可以从我这里把这张图片下载下来,如下图] 操作步骤 下面就是创建法线贴图着色器的步骤了: 让我们设置好我们的属性块,从而可以获得颜色和贴图: Properties { _MainTint ("Diffuse Tint", Color) = (1,1,1,1) _NormalTex ("Normal Map", 2D) = "bump" {} } 注意 因为用的是 bump 来初始化了属性的贴图类型,这等于是告诉了Unity _NormalTex 包含了法线贴图。如果这个贴图没有被设置, 那么会默认给它设置一张灰色的贴图。颜色值会用 (0.5,0.5,0.5,1) ,然后看不出一点凹凸感。 在 CGPROGRAM 下面的 SubShader{} 块中声明下面两个变量,让这两个变量跟属性块中的两个属性关联起来: CPROGRAM #pragma surface surf Lambert // Link the property to the CG program sampler2D _NormalTex; float4 _MainTint; 我们需要修改 输入结构体Input struct 的名字,从而让我们可以让我们通过模型的UV来访问法线贴图: ...