user2259784
user2259784

Reputation: 349

Transform Normal and Tangent from Object space to World space?

As to correctly transform the Normal (which is a direction not a position) from Object space to World space, we multiply it with inverse of Model matrix/_World2Object matrix (in Unity).

Then why Tangent (which is tangent to normal and is direction as well - its not a position) is multiplied with Model Matrix /_Object2World (in Unity) to transform it to World space?

eg code : Code for reading Tangent space normal in shader :

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 );

Upvotes: 1

Views: 14483

Answers (3)

顾宇峰
顾宇峰

Reputation: 1

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
}

Upvotes: 0

FadeToBlack
FadeToBlack

Reputation: 39

I have figured out how your code actually works. If you consider matrix by vector multiplication rules, you can figure out the following:

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

where

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

so, you have two identical transform alternatives:

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

Upvotes: 0

Gnietschow
Gnietschow

Reputation: 3180

The normal vector is transformed with the transpose of the inverse model matrix from object space to world space (because it is orthogonal to a surface) while the tangent vector specifies a direction between points on a surface and is therefore transformed with the model matrix.

(Source: Wikibooks)

For a better visualization I drawed a little image: Normal & Tangent transformation

The tangent is a direction on the surface and so if the y axis is squashed it does the same to follow the surface (so the model matrix is used).

The normal is a direction perpendicular to the surface and so if the y axis is squashed it moves the inverse way to stay perpendicular (so the inverse transpose model matrix is used).

Upvotes: 9

Related Questions