
法线贴图的每个像素包含一个向量,指向一个特定的方向。方向向量的范围在[-1,1]之间,而颜色所表示的范围是在[0,1]之间,所以颜色和方向的映射关系为:color=(v+1)*0.5。一般来说,法线贴图存储着每个点在各自的切线空间中的shading法线偏移(扰动)方向,如果一个点的法线方向不变,那么顶点在切线空间中的方向向量为(0,0,1),扰动方向也是在(0,0,1)的周围,根据刚才的映射公式得到颜色值为(0.5,0.5,1),所以显示出来的法线贴图是浅蓝紫色了。法线贴图可以用3dmax,blender等建模软件烘培。
法线贴图解码出来的法线信息是在切线空间,不是世界空间的法线。所以,我们需要把法线从切线空间转到世界空间。先从模型获取网格数据,根据语义绑定,能得到法线方向和切线方向。
struct MeshData { float4 vertex:POSITION;
float3 normal:NORMAL; //模型空间的法线
float3 tangent:TANGENT; //切线 }
Interpolators vert(MeshData v){
Interpolators o;
o.vertex=UnityObjectToClipPos(v.vertex);
o.normal=UnityObjectToWorldNormal(v.normal);
o.tangent=UnityObjectToWorldDir(v.tangent.xyz);
o.bitangent=cross(o.normal,o.tangent)*(v.tangent.w*unity_WorldTransformParams.w);
o.wPos=mul(unity_ObjectToWorld,v.vertex);
}
v.tangent.w :值为-1或者1,由引擎中的切线自动生成,和顶点的环绕顺序有关。
w*unity_WorldTransformParams.w :定义于unityShaderVariables.cginc中.模型的Scale值是三维向量,即xyz,当这三个值中有奇数个值为负时(1个或者3个值全为负时),unity_WorldTransformParams.w=-1,否则为1.
这两个主要是防止翻转的问题。
再看看片元阶段
float4 frag(Interpolators i):SV_Target{
//因为要用法线贴图的法线,这里的原始网格法线就注释了
//float3 N=normalize(i.normal);
//tex2D(_Normals,i.uv)得到的是颜色值,在(0,1)之间,因为UnpackNormal()解码出来的是向量值,
即UnpackNormal()里做了映射处理,colorValue*2-1,映射在(-1,1)之间的范围,
即是顶点的法线方向
float3 tangentSpaceNormal=UnpackNormal(tex2D(_Normals,i.uv));
float3x3 mtxTangToWorld={
i.tangent.x,i.bitangent.x,i.normal.x,
i.tangent.y,i.bitangent.y,i.normal.y,
i.tangent.z,i.bitangent.z,i.normal.z
};
float3 N=mul(mtxTangToWorld,tangentSpaceNormal);
float3 L=normalize(UnityWorldSpaceLightDir(i.wPos));
float attenuation=LIGHT_ATTENUATION(i);
float3 lambert=saturate(dot(N,L));
float3 diffuseLight=(lambert*attenuation)*_LightColor0.xyz;
//specualr lighting
float3 V=normalize(_WorldSpaceCameraPos-i.wPos);
float3 H=normalize(L+V); //半角向量
float3 specularLight=saturate(dot(H,N))*(lambert>0); //Bling-Phong
float specularExponent=exp2(_Gloss*11)+2;
specularLight=pow(specularLight,specularExponent)*_Gloss*attenuation;
specularLight*=_LightColor0.xyz;
return float4(diffuseLight*_Color+specularLight,1);
}
以上代码里,构建矩阵,把法线信息从切线空间转到世界空间。利用该空间下的法线信息去计算模型光照。
浙公网安备 33010602011771号