Math Vector Normalize

问题

在计算切空间下的法线向量时候遇到一个计算公式

1
2
3
float3 tangentNormal = UnpackNormal(packedNormal);
tangentNormal.xy *= _BumpScale;
tangentNormal.z = sqrt(1.0-saturate(dot(tangentNormal.xy,tangentNormal.xy)));

那这个tangentNormal.z为何可以用这个公式得到

求解

什么是Normalize

Y2B视频

Normalize也就是向量的归一化.

用向量除上自身的模儿也就是该方向的单位向量

比如

向量点乘自身

dot product
Since the projection of a vector on to itself leaves its magnitude unchanged, the dot product of any vector with itself is the square of that vector’s magnitude. > Applying this corollary to the unit vectors means that the dot product of any unit vector with itself is one.

向量点乘自身得到的也就是自身模儿的平方.

二维向量 向量a = <x,y>

dot(向量a,向量a) = x^2 + y^2

tangentNormal.z

对于三维单位向量(x,y,z)其模儿公式为 (因为单位向量的定义就是其模儿等于1)

1^2 = x^2 + y^2 + z^2

1
2
3
4
public static float SqrMagnitude(Vector3 vector)
{
return (float) ((double) vector.x * (double) vector.x + (double) vector.y * (double) vector.y + (double) vector.z * (double) vector.z);
}

所以就应该可以得到

1
tangentNormal.z = sqrt(1.0-dot(tangentNormal.xy,tangentNormal.xy)));

至于saturate 也就是将后面的值范围缩小到0~1. 我猜想是因为前面 * _BumpScale 但是结果又不希望发现z值反向了.

换句话说就 通过NormalMap 控制原有法线在 180度的 半球形平面内发生改变. 从而体现出 物体的凹凸质感. 如果z<0了,等于法线就进入到平面的”内”侧了. 从而无法产生正常的光照效果.

坚持原创技术分享,您的支持将鼓励我继续创作!