上次我们学习了如何进行颜色混合!在该教程中,你需要知道如何混合颜色,所以如果你还没学过,请仔细阅读。
还记得我们在系列第一节材质中玩球体和胶囊体的时候,材质呈现出一种亮蓝色/紫色的纹理,让瓷砖看起来就像真的从物体里冒出来一样吗?太酷了,让我们用着色器来实现这个效果吧!
那个蓝紫色的纹理叫做法线贴图。它包含关于 3D 物体应该呈现出怎样的凹凸效果的信息。法线贴图很有用,因为它们可以让细节较少的 3D 物体看起来比实际更细致。(我们很难为了模型凹凸感去修改顶点信息,这很难)不过,我们稍后会详细讨论这一切的工作原理。
在 Unity 中,点击 Lerp 着色器,然后按 Ctrl + D 复制它,并将其命名为 XibStandard。双击以在 Visual Studio 中打开它。首先,让我们将顶部的路径更新为“Xibanya/XibStandard”。
在属性部分,添加以下行:
_BumpMap("Normal", 2D) = "bump" {}
在 SubShader 部分中,在其他 sampler2D 行下添加此行:
sampler2D _BumpMap;
完成后,您的代码应如下所示:
顺便说一下,在属性的顶部,你会看到 2D 类型的属性有些显示“white”,而我们刚刚添加的属性显示“bump”
我们在这里输入“white”,指的是如果插槽中没有任何纹理,默认的颜色应该是什么。我们在这里输入“bump”,指的是放置法线贴图的插槽,因为如果插槽中没有任何纹理可放,在这里输入“bump”将使用默认的法线贴图信息,这意味着 3D 对象看起来还是正常的。
在此表面函数中,添加此行
o.Normal = UnpackNormal(tex2D(_BumpMap,IN.uv_MainTex));
首先,我们通过告诉着色器查看插槽中的纹理,然后应用主纹理的UV坐标,并通过该坐标信息拾取颜色来获取法线贴图纹理的颜色。然后,UnpackNormal 函数将颜色信息转换为法线信息(关于物体应该有多么凹凸不平的信息)。你应该记得,这里的o存储物体应该会有什么样子的输出,而o.Normal就是我们保存物体应该有多么凹凸不平信息的地方。
当你完成上述代码时,保存,然后单击返回 Unity。
前往“Claire”>“Materials”文件夹,复制“ClaireBody2”。点击“ClaireBody3”,其信息就会显示在检查器中。
在下拉菜单中,选择着色器 Xibanya > XibStandard。现在将 ClaireBody3 拖到 Girl_Body_Geo 的材质槽中。
法线贴图插槽自动填充了克莱尔的法线贴图。这是为什么呢?因为 Unity 中的材质会保存其所有属性,而我们一直在不断复制。所以,材质保存了法线贴图纹理和名为“_BumpMap”的属性之间的链接。我们稍后会讨论这个问题。如果你的材质没有自动填充,请将克莱尔的法线贴图拖到插槽中。
现在克莱尔有了法线贴图,混合两种纹理会更有趣,因为即使不再使用她的主纹理,你也可以看到她的细节。
好了,既然我们前面已经混合了颜色,为什么不也混合一下凹凸效果呢?回到代码,并将其更新为如下所示:
保存并返回 Unity。将图块状的法线贴图拖到新插槽中。现在你应该能看到如下内容:
注意,第二张法线贴图"Normal2"完全没有设置不等于1的Tiling值,即它没有缩放,但它仍然与平铺纹理(OtherTex)匹配,即使平铺纹理(OtherTex)比默认纹理小了 5 倍。这是因为我们告诉着色器在解析第二张法线贴图时使用第二张纹理(即 IN.uv_OtherTex )的坐标。这使它们保持同步。我们对第一张法线贴图也做了同样的操作。
让我们来看看这张法线贴图的完整效果。点击层级视图(左上角窗格中场景中的节点列表)中的定向光源,取消勾选光源组件旁边的复选框以将其关闭。
接下来,右键单击 claire@Female Standing Pose 并添加一个新的点光源。
通过右键单击克莱尔来添加它,这会使新的灯光嵌套在克莱尔下方,并且与她所在的位置完全重叠。会产生如下戏剧化的效果!
让我们拖动箭头手柄,让光线照射在她的脸上。
拖动灯光时,你可以看到克莱尔实际上是由瓷砖图块拼成的。为了获得完整的效果,你可以点击“场景”选项卡顶部附近的图标来关闭天空盒,这个图标看起来像一叠闪闪发光的纸(或者两颗短而宽的钻石和一颗星光?)。
但这里有个挺有意思的地方!看起来好像有一排排凸起的瓷砖,瓷砖之间还有凹槽,但放大她的脸,看看网格的边缘。
它们非常光滑!3D网格中实际上没有任何凹槽,只是因为光照效果的原因,使得表面看起来凹凸不平。所以,无论我们在表面函数的 o.Normal 中输入什么信息,3D物体的实际形状都不会改变。尽管如此,仅仅改变光照效果就相当逼真,尤其是在远处的角度观看时!
(顺便说一句,我们有办法用着色器改变 3D 对象的形状,但我们改天再讨论这个想法。)
那么,如果我们想要法线贴图更强大呢?通常,当我们谈论着色器时,法线由 3 个数字组成,但这些数字并非代表红、绿、蓝。而是代表 x、y 和 z 轴的数字,它们用于指示方向。如果我们在桌子上放一张纸,我们可以使用 x 和 y 来表示基于宽度和高度的坐标。纸的中心是 0,0,所以如果我们有其他坐标,那么从中心到该坐标绘制的线就是方向。z 轴增加了深度(即上下),但在 3D 中寻找方向仍然需要从 0,0,0 绘制一条到另一点的假想线作为方向指向。
所以实际上,我们所说的法线并非指“凹凸程度”,而是指3D网格各部分朝向的方向。不过现在你不需要太担心这个。
Z 是沿着上下方向的,因此如果我们弄乱了法线的 Z,那么我们就会弄乱 3d 网格表面突出的程度。
更新属性以包含此新行
并在 _Mix 下声明新的 Float类型的 Uniform变量,如下所示:
然后在surf表面函数中我们再添加一行:
保存并返回 Unity。点击“Normal Strength”框旁边,然后向左拖动。哇哦。
尝试向下拖动“Mix”混合滑块来查看其与克莱尔的法线贴图的搭配效果。
咦!看看当我们接近零时,光亮部分和阴影部分之间的对比度变得越来越鲜明。
如果我们朝相反的方向走,光的颜色和阴影的颜色之间的差异就会变得更加平滑。
挺有意思的,你不觉得吗?我猜我们肯定能用上它。
好了,目前为止我只能做到这些了。如果你想挑战一下,可以试试添加一个属性,这样就能分别控制两个法线贴图的强度了。如果你需要任何帮助,评论区中尽管告诉我!
进入第 6 部分:让物体发光!