将对象空间中的法线和切线变换为世界空间?

时间:2016-01-29 19:52:22

标签: matrix shader game-engine hlsl cg

为了正确地将Normal(不是位置的方向)从Object空间转换为World space,我们将它与Model matrix / _World2Object矩阵的逆(在Unity中)相乘。

那么为什么Tangent(它与法线相切并且也是方向 - 它不是一个位置)与Model Matrix / _Object2World(在Unity中)相乘以将其转换为世界空间?

例如代码:用于在着色器中读取正切空间法线的代码:

o.normalWorld = normalize( mul(v.normal, _World2Object) );
o.tangentWorld = normalize( mul(_Object2World, v.tangent) );
o.binormalWorld = normalize( cross(o.normalWorld, o.tangentWorld) * v.tangent.w );

3 个答案:

答案 0 :(得分:5)

  

通过逆的转置来转换法向量   从对象空间到世界空间的模型矩阵(因为它是   正交到表面)而切线向量指定a   表面上的点之间的方向因此被转换   用模型矩阵。

(资料来源:Wikibooks

为了更好的可视化,我绘制了一个小图像: Normal & Tangent transformation

切线是曲面上的方向,因此如果y轴被压扁,它会跟随曲面一样(因此使用模型矩阵)。

法线是垂直于曲面的方向,因此如果y轴被压扁,它将以相反的方式移动以保持垂直(因此使用逆转置模型矩阵)。

答案 1 :(得分:0)

我已经弄明白你的代码是如何运作的。 如果按矢量乘法规则考虑矩阵,可以计算出以下内容:

v * m <=> m^-1 * v

,其中

v is vector(row or column, regarding to it's position)
m is matrix
^-1 is inverse operator

所以,你有两个相同的转换选择:

o.normalWorld = normalize( mul(v.normal, _World2Object) );
<=>
o.normalWorld = normalize( mul(_Object2World, v.normal) );

答案 2 :(得分:0)

to FadeToBlack:
  to be more accurate it is: 
  mul(IT_M, norm) => mul(norm, I_M) => 
  {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
IT_M is the inverse tanspose matrix of M. See all the code in Unity shader function: UnityObjectToWorldNormal which is:

// Transforms normal from object to world space
inline float3 UnityObjectToWorldNormal( in float3 norm )
{
#ifdef UNITY_ASSUME_UNIFORM_SCALING
    return UnityObjectToWorldDir(norm);
#else
    // mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
    return normalize(mul(norm, (float3x3)unity_WorldToObject));
#endif
}