法线贴图 (Normal Map)

解包NormalMap (Unpack NormalMap)


x向量存在a通道,y在g通道。而那种黄色的法线贴图是x在r通道,y在g通道,如果把b加上就会变成常见的蓝紫色Normal。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//UnityStandardUtils.cginc中的解包方法
half3 UnpackScaleNormal(half4 packednormal, half bumpScale)
{
#if defined(UNITY_NO_DXT5nm)
return packednormal.xyz * 2 - 1;
#else
half3 normal;
normal.xy = (packednormal.wy * 2 - 1);
#if (SHADER_TARGET >= 30)
// SM2.0: instruction count limitation
// SM2.0: normal scaler is not supported
normal.xy *= bumpScale;
#endif
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
return normal;
#endif
}

half3 unpackedNormal = UnpackScaleNormal(tex2D(_BumpMap, i.uv.xy), _Bumpness);

转换到世界空间去 (From Tangent Space to World Space)

转换到世界空间需要到对应点在世界的转换矩阵。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tangentWorld = normalize(
mul(_Object2World, half4(v.tangent.xyz, 0.0)).xyz);

normalWorld = normalize(
mul(half4(v.normal, 0.0), _World2Object).xyz);

bitangentWorld = normalize(
cross(o.normalWorld, o.tangentWorld)
* v.tangent.w);

half3x3 local2WorldTranspose = half3x3(
tangentWorld,
bitangentWorld,
normalWorld
);

关于Normal, Tangent和Bitangent(Binormal)的解释:
Tangent space matrix (TBN)
What are normal, tangent and binormal vectors and how are they used.

最后获得世界空间的Normal

1
half3 normalDir = normalize(mul(unpackedNormal, local2WorldTranspose));
分享