// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
Shader "Unity Shader Book/Chapter 7/MaskTexture"
{
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
_ShadowMask("Shadow Mask", 2D) = "white" {}
_ShadowScale("Shadow Scale", Float) = 1.0
_Specular("Specular", Color) = (1, 1, 1, 1)
_Gloss("Gloss", Range(8.0, 256)) = 20
}
SubShader
{
Tags{"Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout"}
// No culling or depth
Pass
{
Tags{ "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT; //顶点切线方向 tangent.w 分量来决定切线空间中的第三个坐标轴(福切线的方向性)
float4 texcoord : TEXCOORD0; //纹理坐标
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 lightDir : TEXCOORD1;
float3 viewDir : TEXCOORD2;
};
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _BumpMap;
float _BumpScale;
sampler2D _SpecularMask;
float _SpecularScale;
sampler2D _ShadowMask;
float _ShadowScale;
fixed4 _Specular;
float _Gloss;
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex); //模型裁剪空间的坐标
//主贴图uv坐标 = 自身缩放 * 主贴图缩放 + 主贴图偏移值
o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
//构造出 tangent space 的坐标系, 定义转换world space的向量到tangent space的rotation 矩阵。
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);//统一化视角方向
//模型空间法线纹理方向 覆盖纹理
fixed3 tangentNormal = UnpackNormal(tex2D(_BumpMap,i.uv));
tangentNormal.xy *= _BumpScale; //纹理缩放比例
//法线阴影程度
tangentNormal.z = sqrt(1.0 - saturate(dot(tangentNormal.xy, tangentNormal.xy)));
//自身颜色 = 贴图颜色 + 设置颜色
fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;
//自身颜色 = 系统灯光颜色(天空盒子) + 设置颜色
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
//漫反射 = 灯光颜色 * 自身颜色 * 法线方向到灯光方向的角度(0是背面 1是正面)
fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(tangentNormal, tangentLightDir));
//灯光到视角的反方向
fixed3 halfDir = normalize(tangentLightDir + tangentViewDir);
//遮罩 = 覆盖纹理 遮码值(r) * 缩放大小
fixed specularMask = tex2D(_SpecularMask, i.uv).r * _SpecularScale;
fixed shadowMask = tex2D(_ShadowMask, i.uv).r * _ShadowScale;
//反射 = 灯光颜色 * 设置颜色 * pow(反射角度(取值范围0~1), 程度) * 遮罩 * 遮罩 双层遮罩
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0,dot(tangentNormal,halfDir)),_Gloss) * specularMask * shadowMask;
//灯光颜色 + 自身颜色 + 高光颜色
return fixed4(ambient + diffuse + specular,1.0);
}
ENDCG
}
}
Fallback "Specular"
}