本文借鉴《Unity Shader入门精要》,算是对自己学习的总结,也希望分享下所学知识~~
在高光反射中,之前把所有的像素都是用同样大小的高光强度和高光指数。
但是有时希望模型表面某些区域的反光强一些,而某些区域的若一些。
为了得到这样的细腻效果,需要引入一张 遮罩纹理 来控制光照。
原理:
通过采样得到遮罩纹理的纹素值,然后使用其中某几个通道的值来与某种表面属性进行相乘。
当通道的值为 0 即不受影响。
Shader "zhangjx/_10014MaskTexture"
{
Properties
{
_Color ("Color Tint", Color) = (1,1,1,1)
_MainTex("Main Tex", 2D) = "white"{}
_BumpMap ("Normal Map", 2D) = "bump" {}
_BumpScale("Bump Scale", Float) = 1.0
_SpecularMask ("Specular Mask", 2D) = "white"{}//遮罩纹理
_SpecularScale ("Specular Scale", Float) = 1.0//遮罩系数
_Specular ("Specular", Color) = (1,1,1,1)
_Gloss("Gloss", Range(8.0, 256)) = 20
}
SubShader
{
Tags { "LightMode" = "ForwardBase" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
#include "UnityCG.cginc"
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _BumpMap;
float4 _BumpMap_ST;
float _BumpScale;
fixed4 _Specular;
float _Gloss;
sampler2D _SpecularMask;
float4 _SpecularMask_ST;
float _SpecularScale;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 lightDir : TEXCOORD1;
float3 viewDir : TEXCOORD2;
};
v2f vert (appdata_tan v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
TANGENT_SPACE_ROTATION;
o.lightDir = mul(rotation, ObjSpaceLightDir( v.vertex )).xyz;
o.viewDir = mul(rotation, ObjSpaceViewDir( v.vertex )).xyz;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 tangentLightDir = normalize( i.lightDir );
fixed3 tangentViewDir = normalize( i.viewDir );
fixed4 packedNormal = tex2D( _BumpMap, i.uv );
fixed3 tangentNormal;
tangentNormal = UnpackNormal( packedNormal );
tangentNormal.xy *= _BumpScale;
tangentNormal.z = sqrt( 1.0 - saturate( dot(tangentNormal.xy, tangentNormal.xy) ) );
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 albedo = tex2D( _MainTex, i.uv ).rgb * _Color.rgb;
fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(tangentNormal, tangentLightDir));
fixed3 halfDir = normalize( tangentLightDir + tangentViewDir );
fixed specularMask = tex2D( _SpecularMask, i.uv ).r * _SpecularScale;//计算高光遮罩颜色
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow( max(0, dot(tangentNormal, halfDir)), _Gloss) * specularMask;//相乘混合
return fixed4(ambient+diffuse+specular, 1.0);
}
ENDCG
}
}
FallBack "SPECULAR"
}