shader "xxg/13_NormalMap"
{
Properties{
_Color("Color",Color)=(1,1,1,1)
_MainTex("Main tex",2D) = "White"{}
_NorlmalMap("Normal Map",2D) = "bump"{}//法线贴图
_BumpScale("BumpScale",Float)=1
}
SubShader{
Pass{
Tags{"LightMode" = "ForWordBase"}
CGPROGRAM
include "Lighting.cginc"
pragma vertex vert
pragma fragment frag
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;//maps Tiling+Offset(固定写法)缩放?、偏移?
sampler2D _NormalMap;
float4 _NormalMap_ST;
float _BumpScale;
struct a2v {
float4 vertex:POSITION;
//切线空间的确定是通过存贮到模型里面的法线和存在到模型里面的切线确定的
float3 normal:NORMAL;
float4 tangent:TANGENT;//targent,w是用来确定切线空间中坐标轴的方向的。
float4 texcoord:TEXCOORD0;
};
struct v2f {
float4 svPos:SV_POSITION;
float3 lightDir:TEXCOORD0;
float4 uv:TEXCOORD1;//xy用来储存MainTex的纹理坐标,zw用来储存NormalMap的纹理坐标
};
v2f vert(a2v v) {
v2f f;
f.svPos = UnityObjectToClipPos(v.vertex);
//f.worldVertex = mul(v.vertex,unity_WorldToObject);
f.uv.xy = v.texcoord.xy*_MainTex_ST.xy+ _MainTex_ST.zw;//*缩放倍数+偏移
f.uv.zw = v.texcoord.xy*_NormalMap_ST.xy + _NormalMap_ST.zw;
TANGENT_SPACE_ROTATION;//调用这个之后,会得到一个矩阵,rotation,这个矩阵用来把切线空间下的方向转换成模型空间下
//ObjSpaceLightDir(v.vertex)//得到模型空间下的平行光方向
f.lightDir=mul(rotation,ObjSpaceLightDir(v.vertex));
return f;
}
//把所有跟法线方向有关的运算都放在,切线空间下
//把法线贴图里面取得的法线方向是值切线空间下的
fixed4 frag(v2f f) :SV_TARGET
{
fixed4 normalColor = tex2D(_NormalMap,f.uv.zw);
//fixed3 tangentNormal = normalColor.xyz * 2 - 1;//切线空间下的法线
fixed3 tangentNormal = UnpackNormal(normalColor);
tangentNormal.xy = tangentNormal.xy*_BumpScale;
tangentNormal = normalize(tangentNormal);
fixed3 lightDir = normalize(f.lightDir);
fixed3 texColor = tex2D(_MainTex,f.uv.xy)*_Color.rgb;
fixed3 diffuse = _LightColor0.rgb*texColor*max(dot(tangentNormal,lightDir), 0);
fixed3 tempColor = diffuse + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor;
return fixed4(tempColor,1);
}
ENDCG
}
}
Fallback "Specular"
}