遮罩纹理
Contents
遮罩纹理是用来做什么的
遮罩纹理通常用于控制或限制某些效果的显示范围。 它允许我们可以保护某些区域,使它们免于某些修改。 一般情况下,遮罩纹理也会是一张灰度图,其中的RGB值会是相同的 我们利用它存储的值参与到
- 光照(指定某些区域受光影响的程度)
- 透明度(指定某些区域透明的程度)
- 特效(指定某些区域出现特效) 等等相关的计算中 从而来让指定区域达到我们想要的效果
高光纹理遮罩
利用高光遮罩纹理 我们可以控制模型上的各个区域受到高光影响的强弱
基本原理
- 从纹理中取出对应的遮罩掩码值(颜色的RGB值都可以使用)
- 用该掩码值和遮罩系数(我们自己定义的)相乘得到遮罩值
- 用该遮罩值和高光反射计算出来的颜色相乘
fixed specularMask = tex2D(_SpecularTex,i.uv.xy).r * _SpecularScale;//高光遮罩
float3 halfDir = normalize(i.viewDir + i.lightDir);
fixed3 specularColor = _LightColor0 * _SpecularColor * pow(max(0,dot(halfDir,unpackNormal)),_SpecularNum) * specularMask;综合实现
Shader "Unlit/SpecularMask"
{
Properties
{
_MainTex("MainTex",2D) = ""{} //主贴图
_NormalTex("NormalTex",2D) = ""{} //法线贴图
_BumpScale("BumpScale",range(0,1)) = 1 //凹凸度
_DiffuseColor("DiffuseColor",Color) = (1,1,1,1) //漫反射颜色
_RampTex("RampTex",2D) = ""{} //渐变贴图
_SpecularColor("SpecularColor", Color) = (1,1,1,1) //高光反射颜色
_SpecularNum("SpecularNum", Range(8, 256)) = 18 //光泽度
_SpecularTex("SpecularTex",2D) = ""{}//高光遮罩纹理
_SpecularScale("SpecularScale",range(0,1)) = 1 //高光遮罩系数
}
SubShader
{
Pass
{
Tags { "LightMode"="ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
float4 wpos : TEXCOORD1;
float3 viewDir:TEXCOORD2;
float3 lightDir:TEXCOORD3;
};
//漫反射
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _DiffuseColor;
sampler2D _RampTex;
//法线
sampler2D _NormalTex;
float4 _NormalTex_ST;
float _BumpScale;
//高光反射
fixed4 _SpecularColor;
float _SpecularNum;
sampler2D _SpecularTex;
float _SpecularScale;
v2f vert (appdata_full v)
{
v2f data;
//坐标转换
data.pos = UnityObjectToClipPos(v.vertex);
data.wpos = mul(unity_ObjectToWorld,v.vertex);
//uv贴图
data.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
data.uv.zw = v.texcoord.xy * _NormalTex_ST.xy + _NormalTex_ST.zw;
//计算 切线空间 变换矩阵
float3 bitangent = cross(v.tangent.xyz,v.normal) * v.tangent.w;
float3x3 rotation = float3x3(v.tangent.xyz,bitangent,v.normal);
//切线空间下的 视角和灯光向量
data.viewDir = mul(rotation,ObjSpaceViewDir(v.vertex));
data.lightDir = mul(rotation,ObjSpaceLightDir(v.vertex));
return data;
}
fixed4 frag (v2f i) : SV_Target
{
//法线
float4 packedNoraml = tex2D(_NormalTex,i.uv.zw);
float3 unpackNormal = UnpackNormal(packedNoraml);
//凹凸度
unpackNormal.xy *= _BumpScale;
unpackNormal.z = sqrt(1 -saturate(dot(unpackNormal.xy,unpackNormal.xy)));
//漫反射
fixed3 uvColor = tex2D(_MainTex,i.uv.xy) * _DiffuseColor.rgb;
fixed halfLarbertNum = dot(i.lightDir,unpackNormal) * 0.5 + 0.5;//渐变贴图
fixed3 diffuseColor = _LightColor0 * uvColor * tex2D(_RampTex,fixed2(halfLarbertNum,halfLarbertNum));
//高光
fixed specularMask = tex2D(_SpecularTex,i.uv.xy).r * _SpecularScale;//高光遮罩
float3 halfDir = normalize(i.viewDir + i.lightDir);
fixed3 specularColor = _LightColor0 * _SpecularColor * pow(max(0,dot(halfDir,unpackNormal)),_SpecularNum) * specularMask;
//blinn-phong
fixed3 blinnPhongColor = UNITY_LIGHTMODEL_AMBIENT * uvColor + diffuseColor + specularColor;
return fixed4(blinnPhongColor,1);
}
ENDCG
}
}
}