# _Object2World or UNITY_MATRIX_IT_MV?

Discussion in 'Shaders' started by sbin3776, Nov 19, 2011.

1. ### sbin3776

Joined:
Oct 31, 2011
Posts:
18
In unity's vertex shader，I need transform v.normal to world space, but I don't understand _Object2World and UNITY_MATRIX_IT_MV. Which one should I use?
mul( (float3x3)_Object2World, v.normal) or mul( (float3x3)UNITY_MATRIX_IT_MV, v.normal ) ?

### Unity Technologies

Joined:
Aug 11, 2006
Posts:
3,355
UNITY_MATRIX_IT_MV is for rotating normals from object into eye space.

3. ### sbin3776

Joined:
Oct 31, 2011
Posts:
18
That means that I should use _Object2World for rotating v.normal from objectspace into worldspace?

4. ### kev42100

Joined:
Apr 17, 2010
Posts:
61
I think you wanted to say : UNITY_MATRIX_IT_MV is for rotating normals from eye into object space.
Inverse Transpose matrix.

To sbin3776 : Yes, use _Object2World, the name is quite explicit

### Unity Technologies

Joined:
Aug 11, 2006
Posts:
3,355
No, what I wrote is correct. You can read a derivation of inverse transpose model view matrix (also called the normal matrix) here.

6. ### Martin-Kraus

Joined:
Feb 18, 2011
Posts:
617
To transform normals from object to world space, use _World2Object but multiply it from the right hand side to the vector (this makes sure that you multiply the vector with the transposed matrix). (The "IT" in "UNITY_MATRIX_IT_MV" stands for Inverse Transpose" which is what you need for the correct transformation of normal vectors.)

If you are sure that your model matrix is orthogonal (no scaling), you can also use _Object2World (from the left hand side).

### Unity Technologies

Joined:
Aug 11, 2006
Posts:
3,355
This is incorrect. The transpose of World2Object is the transpose of the inverse of the Object2World matrix.
• MV transforms points from object to eye space
• IT_MV rotates normals from object to eye space
And similarly:
• Object2World transforms points from object to world space
• IT_Object2World (which, as you point out, is the transpose of World2Object) rotates normals from object to world space
If it is orthogonal, the upper-left 3x3 of Object2World will be equal to that of IT_Object2World, and so will also rotate normals from object to world space.

8. ### Martin-Kraus

Joined:
Feb 18, 2011
Posts:
617
What is incorrect?

### Unity Technologies

Joined:
Aug 11, 2006
Posts:
3,355
Oops. For some reason I read "world to object" instead of "object to world" in your post. You're right, and I pretty much just repeated what you said.

10. ### sbin3776

Joined:
Oct 31, 2011
Posts:
18

but
How can I know the model matrix is orthogonal ?
if it is not orthogonal ,Should I use _World2Object buy multiply it from the right hand side to the normal vector ?
Which of the following is correct:
1 mul( (float3x3) _Object2World ,v.normal ) ; //model matrix is orthogonal
2 mul ( v.normal, (float3x3) _World2Object ) ;// model matrix is not orthogonal
3 mul ( v.normal, (float3x3) transpose( _World2Object) ) ;// model matrix is not orthogonal
4 mul ( (float3x3) transpose( _World2Object) , v.normal ) ;// model matrix is not orthogonal
-------------------------------------------------------------
I think 3 is incorrect and 2==4

Last edited: Nov 22, 2011
11. ### stford

Joined:
Sep 7, 2010
Posts:
5
Related question
how do I grab the matrix in GLSL from the setMatrix() over in javaScript

steve

12. ### Martin-Kraus

Joined:
Feb 18, 2011
Posts:
617
You think correctly.

A 3x3 matrix is orthogonal if all row vectors (or all column vectors) are of unit length and the dot product of any two row vectors (or column vectors) is 0.

13. ### Martin-Kraus

Joined:
Feb 18, 2011
Posts:
617
You define a uniform matrix outside of main():

uniform mat4 mymatrix;

You can set the variable mymatrix with setMatrix() (even though you cannot define a property).

14. ### Trung-Hieu

Joined:
Feb 18, 2013
Posts:
37
Isn't that the definition of orthonormal matrices ?
In orthogonal matrices, only all the row vector (or all the column vectors) are perpendicular to each other.

grubertm likes this.
15. ### 00christian00

Joined:
Jul 22, 2012
Posts:
1,035
Is it possible to rotate the normals into eye space specifying the camera position manually, ignoring the current camera position?

16. ### Billy4184

Joined:
Jul 7, 2014
Posts:
6,057
Hey guys, if you're making an endless runner moving along the z axis and you need to use a projection matrix that is relative to the camera but is not affected by rotation, then just subtract the camera world position z from the vPos.z, i.e.:

Code (CSharp):
1.
2. float4 vPos = mul (_Object2World, v.vertex);
3. float zOff = (vPos.z - _WorldSpaceCameraPos.z)/_Dist;     // offset relative to camera along the z axis
4. vPos += _QOffset*zOff*zOff; //
5. v.vertex = mul (_World2Object, vPos);
6.