Unity Shader入门系列(四):颜色混合

Number of views 15

上次我们讨论了颜色的添加方式。今天我们来稍微混合一下。在 Shaders 文件夹中,点击上次创建的名为 ColorAdd 的着色器,然后按下ctrl + D。这将复制该着色器。点击副本并将其重命名为Lerp

image1753760475765.png

前往克莱尔的材质文件夹,点击“ClaireBody1”,然后按 ctrl + D 复制它。它会自动命名为“ClaireBody2”,这样就没问题了。

单击层次结构中的 Girl_Body_Geo 并将 ClaireBody2 拖入材质槽。

image1753760518383.png

如果您尝试从下拉菜单中将新的着色器添加到材质上,您将无法找到它。这是因为着色器的名称并非来自文件名,而是来自着色器文件中包含路径的第一行有效代码。返回项目文件中的新着色器,双击它以在 Visual Studio 中打开它。

在顶部,将路径从“Xibanya/ColorAdd”更改为“Xibanya/Lerp”,像这样。 

image1753760537533.png

保存并返回 Unity。现在,在材质着色器下拉菜单中,选择“Xibanya”>“Lerp”,将着色器添加到材质上。克莱尔看起来和之前一样,因为我们还没有做任何改动!

回到着色器代码。我们要添加另一个纹理槽。在属性部分,删除包含 _AddColor 的行,并替换为 _OtherTex("Other Tex", 2D) = "white" {}

sampler2D _MainTex; 的正下方,添加一行 sampler2D _OtherTex; 。记住,如果我们在属性部分添加了新内容,也必须在主函数部分声明它!另外,还有一点需要注意:属性部分中的代码行不能以分号结尾,但 SubShader 部分中的代码行必须以分号结尾。现在不用太担心,继续往下看,你做得越多就越容易记住。

在表面函数中(记住,这是 void surf开始的部分),将最后一行从 o.Albedo += _AddColor;更改为

o.Albedo = tex2D(_OtherTex, IN.uv_MainTex).rgb

到目前为止你的着色器代码应该是这样的。

image1753760563823.png

保存并返回 Unity。现在材质属性中应该有第二个纹理槽了。

image1753760588779.png

返回我们之前的那些图块纹理并将图块拖入第二个插槽。 

image1753760629291.png

哎呀,有点乱。记住,当我们叠加颜色时,它们只会比初始颜色更暗!如果我们想混合颜色,比如平均颜色值而不是让它们变暗,我们就得另想办法了。

返回 Visual Studio 并将表面函数更改为如下所示:

image1753760662452.png

我们将把 _MainTex 的颜色保存在一个名为 mainTex 的变量中,并将 _OtherTex 的颜色保存在一个名为 otherTex 的变量中。新的部分是第三行,其中包含插值。 

想象一下渐变。

image1753760681935.png

想象一下,它下面有一把尺子,左边缘下方表示 0,右边缘下方表示 1,正中间表示 0.5。lerp 函数就是这样的。我们第一个输入的颜色相当于渐变左侧的颜色,第二个输入的颜色相当于渐变右侧的颜色,第三个输入的数字表示在渐变的哪个位置(介于 0 和 1 之间)进行颜色混合。因此,由于我们将 0.5 作为 lerp 的第三部分,着色器将从渐变的正中心获取颜色。在 Visual Studio 中保存并返回 Unity,让我们看看会发生什么!

image1753760707967.png

好耶,她不再那么泥泞了! 

让我们在着色器属性中添加一个滑块,这样我们就可以更改渐变中颜色混合的来源,而无需每次都编辑代码。回到 Visual Studio,更新属性,如下所示:

image1753760733705.png

记住,我们必须在 SubShader 部分再次添加新内容。在 Surface 函数上方,添加浮点型 _Mix;然后在 lerp 函数中,将 0.5 改为 _Mix;这意味着 lerp 函数将使用我们传入 _Mix 属性的任何数字。最终效果如下:

image1753760762688.png

保存并单击返回 Unity(当您在 Visual Studio 中保存时,Unity 将不会开始重新加载所有内容,直到您单击返回窗口。)

左右拖动新的滑块。你会发现,当滑块值为 0 时,她只使用主纹理;当滑块值为 1 时,她只使用平铺纹理。

image1753760789358.png

这些图块有点大,如果它们小一点会看起来更酷。可惜的是,如果我们拖动图块纹理旁边的平铺/偏移框中的数字,什么也没发生!不用担心,这很容易解决! 

回到代码中,在输入结构中,添加一个新行,使其看起来像这样:

image1753760814247.png

嘿,那到底是什么?好吧,当我们谈论 3D 物体时,uv 指的是 3D 物体外部的位置,所以在这种情况下,你可以把它们想象成纹理上的坐标。 

让我们看看如何获取纹理。

image1753760834000.png

tex2D是一个类似 lerp 的函数。它由两部分组成。(如果你想从技术角度理解,这两部分可以称为参数。)第一部分是我们要从中获取颜色的纹理,也就是我们拖进插槽的东西!那么IN.uv_MainTex部分是什么呢?

这里的 IN 代表输入,它是我们想要为其着色的 3D 对象的信息。如果我们在它后面加上 . ,就可以从之前传入 Input 结构体的内容中获取信息。因此,IN.uv_MainTex 会获取主纹理的坐标。 

当我们编写 tex2D(_MainTex, IN.uv_MainTex) 时,我们的意思是“查看名为 _MainTex 的纹理,通过纹理坐标 IN.uv_MainTex,然后获取那里的颜色”。

所以当我们写 tex2D(_OtherTex, IN.uv_MainTex) 时,我们的意思是:“查看名为 _OtherTex 的纹理,通过IN.uv_MainTex 的坐标,然后获取那里的颜色。” 之所以调整另一个纹理的比例和偏移量不起作用,是因为我们甚至没有使用另一个纹理的坐标来获取它的颜色。所以现在让我们解决这个问题。

您的表面函数现在应如下所示:

image1753760858176.png

保存并返回 Unity!

将另一个纹理旁边的框中的数字更改为如下所示:

image1753760884453.png

嘿嘿!

image1753760919714.png

着色器的最终版本已附在本帖中。想要挑战一下,可以尝试添加第二个颜色框,并将另一张纹理乘以该颜色。告诉我你的想法!如果你有任何问题或需要帮助,请告诉我!

第 5 部分:法线贴图

0 Answers