为了正确地将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 );
答案 0 :(得分:5)
通过逆的转置来转换法向量 从对象空间到世界空间的模型矩阵(因为它是 正交到表面)而切线向量指定a 表面上的点之间的方向因此被转换 用模型矩阵。
(资料来源:Wikibooks)
切线是曲面上的方向,因此如果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
}