Unity Shader实现纹理遮罩效果
纹理遮罩用处很多,简单来讲就是允许我们可以保护模型中的某些区域不受某些因素的影响。例如我们有时希望模型表面某些区域的反光强烈一些,而某些区域弱一些。为了得到更加细腻的结果,我们需要用一张遮罩纹理来控制该光照。还有一些情况就是某些模型需要多张纹理混合时,此时使用遮罩纹理可以控制如何混合这些纹理。
具体流程为:通过采样得到遮罩纹理的纹素值,然后使用其中某个或者几个通道的值来与某种表面属性进行相乘。当该通道的值为0时,此时该表面属性不受遮罩纹理的影响。
shader代码如下:
Shader"Custom/MaskTexture"
{
Properties
{
_Color("Color",Color)=(1,1,1,1)
_MainTex("MainTex",2D)="white"{}
_BumpMap("NormalMap",2D)="white"{}
_BumpScale("BumpScale",Float)=1.0
_SpecularMask("SpecularMask",2D)="white"{}
_SpecularScale("SpecularScale",Float)=1.0
_Specular("Specular",Color)=(1,1,1,1)
_Gloss("Gloss",Range(8.0,256))=20
}
SubShader
{
Pass
{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragmavertexvert
#pragmafragmentfrag
#include"UnityCG.cginc"
#include"Lighting.cginc"
fixed4_Color;
sampler2D_MainTex;
float4_MainTex_ST;//纹理变量名+_ST为unity内置宏,存储了该纹理的缩放大小和偏移量,分别对应.xy和.zw属性
sampler2D_BumpMap;
float_BumpScale;//控制凹凸程度的变量
sampler2D_SpecularMask;//遮罩纹理
float_SpecularScale;//控制遮罩纹理的可见度
fixed4_Specular;
float_Gloss;
structa2v{
float4vertex:POSITION;
float3normal:NORMAL;
float4tangent:TANGENT;
float4texcoord:TEXCOORD0;
};
structv2f{
float4pos:SV_POSITION;
float2uv:TEXCOORD0;
float3lightDir:TEXCOORD1;
float3viewDir:TEXCOORD2;
};
v2fvert(a2vv)
{
v2fo;
o.pos=UnityObjectToClipPos(v.vertex);
//将_MainTex纹理信息(缩放大小和偏移量以及坐标信息)存储到o.uv.xy中
o.uv.xy=v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;
//unity内置宏,计算并得到从模型空间到切线空间的变换矩阵rotation
TANGENT_SPACE_ROTATION;
//获取切线空间下的光照方向
o.lightDir=mul(rotation,ObjSpaceLightDir(v.vertex)).xyz;
//获取切线空间下的视角方向
o.viewDir=mul(rotation,ObjSpaceViewDir(v.vertex)).xyz;;
returno;
}
fixed4frag(v2fi):SV_Target
{
//将切线空间下的光照方向和视角方向单位化
fixed3tangentLightDir=normalize(i.lightDir);
fixed3tangentViewDir=normalize(i.viewDir);
//获取切线空间下的法向量
fixed3tangentNormal=UnpackNormal(tex2D(_BumpMap,i.uv));
tangentNormal.xy*=_BumpScale;
tangentNormal.z=sqrt(1.0-saturate(dot(tangentNormal.xy,tangentNormal.xy)));
//获取片元上的主纹理,并和变量_Color相乘得到其混合结果
fixed3albedo=tex2D(_MainTex,i.uv).rgb*_Color.rgb;
//获取环境光
fixed3ambient=UNITY_LIGHTMODEL_AMBIENT.xyz*albedo;
//漫反射计算
fixed3diffuse=_LightColor0.rgb*albedo*max(0,dot(tangentNormal,tangentLightDir));
//高光反射计算,其计算方式跟前文的计算一样,这里只能另外跟specularMask的遮罩纹理相乘得到其与遮罩纹理的混合结果
fixed3halfDir=normalize(tangentLightDir+tangentViewDir);
fixedspecularMask=tex2D(_SpecularMask,i.uv).r*_SpecularScale;
fixed3specular=_LightColor0.rgb*_Specular.rgb*pow(max(0,dot(tangentNormal,halfDir)),_Gloss)*specularMask;
returnfixed4(ambient+diffuse+specular,1.0);
}
ENDCG
}
}
FallBack"Specular"
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。