使用遮罩纹理(Mask Texture)来控制模型部分颜色的改变

遇到的问题以及遮罩纹理的制作

之前做的遥现项目要结题了,老师要求我录制一个视频,并且提出如果能让两个模型衣服变一变,有差异化再录制视频效果会更好一些。但是考虑到再找人体模型素材,还需要重新与头部模型拼接,重新绑骨蒙皮,重新部署各种插件,麻烦的不得了,所以擅长偷懒的 我决定只通过修改颜色来让两个模型穿的衣服看起来不那么一样。
首先最开始两个模型是这个样子的。
使用遮罩纹理(Mask Texture)来控制模型部分颜色的改变_第1张图片
如果直接改漫反射颜色的话,由于衣服模型用到的贴图是整张的,所以会出现这样的效果
使用遮罩纹理(Mask Texture)来控制模型部分颜色的改变_第2张图片
这显然不是我们想要的效果,我们并不想改变内衬和领带的颜色,所以我想到了用遮罩纹理去控制颜色的变化,遮罩纹理的制作也非常简单,只要掏出PS对原纹理贴图做些修改就可以了,纹理贴图来自MakeHuman软件。

我们能很容易的找到这张贴图上我们不想改变颜色的地方基本上都是白色,其他部分以灰色为主,所以我们可以把不想动颜色的地方涂成全白

这样一张遮罩纹理贴图就制作完成了!是不是很简单?!

在Unity中使用遮罩纹理

我们有了一张遮罩纹理,那么该如何使用它来控制颜色的变化呢?好吧,其实稍微懂点Shader的人都知道接下来该怎么做了,我们只需要对纹理采样然后判断以下遮罩纹理的颜色,如果颜色为纯白色就不对这一部分的漫反射颜色做任何修改,片元着色器代码如下

fixed4 frag(v2f i) : SV_Target
	{
		fixed3 worldNormal = normalize(i.worldNormal);
		fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
		fixed3 diffuseMask = tex2D(_DiffuseMask, i.uv).rgb;
		fixed3 albedo = tex2D(_MainTex, i.uv).rgb;
		if(diffuseMask.x + diffuseMask.y + diffuseMask.z < 3)//如果不是纯白色则修改颜色
			albedo *= _Color.rgb;
		fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
		fixed3 diffuse = albedo * _LightColor0.rgb * saturate(dot(worldNormal, worldLightDir));
        fixed3 col = ambient + diffuse;
        return fixed4(col, 1.0);
    }

但是这样做会出现这样的效果
使用遮罩纹理(Mask Texture)来控制模型部分颜色的改变_第3张图片
我们会发现衬衫边缘部分会有红色出现,作为一个小白的我怀疑可能是因为纹理采样到片元着色会有插值处理,所以纹理上纯白色部分的边界会和边上的灰色进行插值,导致这一部分片元采样的纹理颜色不是纯白色,所以我加入了一个可供材质面板修改的变量来方便手动找到一个合适的值,让我们边缘部分也能被成功“遮罩”住。

if(diffuseMask.x + diffuseMask.y + diffuseMask.z < _MaskColor)
					albedo *= _Color.rgb;

最后发现当_MaskColor值在1.5左右时就可以保证成功遮罩住整片区域了!最终效果如下图所示
使用遮罩纹理(Mask Texture)来控制模型部分颜色的改变_第4张图片

你可能感兴趣的:(Unity,Shader学习笔记)