日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UNITY_MATRIX_IT_MV[Matrix]

發布時間:2025/7/14 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UNITY_MATRIX_IT_MV[Matrix] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://blog.csdn.net/cubesky/article/details/38682975

?

前面發了一篇關于unity Matrix的文章。

http://blog.csdn.NET/cubesky/article/details/38664143

其中對于一般的Matrix可以說應該有一個清晰的了解了。但是對于UNITY_MATRIX_IT_MV這些matrix估計理解起來還是比較有問題。這里再重點描述一下UNITY_MATRIX_IT_MV。

首先,我們看一下unity中Doc中的描述:

?

UNITY_MATRIX_IT_MVfloat4x4Inverse transpose of model * view matrix.

然后我們來看一下UNITY_MATRIX_IT_MV實際的變換意義

?

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.

?

上面這里很好的描述了UNITY_MATRIX_IT_MV的使用場景,專門針對法線進行變換。但是為什么法線的變換和定點不一樣呢?讓我們來看一篇推導的文章。

?

The gl_NormalMatrix is present in many vertex shaders. In here some light is shed on what is this matrix and what is it for. This section was inspired by the excellent book by Eric Lengyel “Mathematics for 3D Game Programming and Computer Graphics”.

Many computations are done in eye space. This has to do with the fact that lighting is commonly performed in this space, otherwise eye position dependent effects, such as specular lights would be harder to implement.

Hence we need a way to transform the normal into eye space. To transform a vertex to eye space we can write:

vertexEyeSpace = gl_ModelViewMatrix * gl_Vertex;

So why can’t we just do the same with a normal vector? A normal is a vector of 3 floats and the modelview matrix is 4×4. Secondly, since the normal is a vector, we only want to transform its orientation. The region of the modelview matrix that contains the orientation is the top left 3×3 submatrix. So why not multiply the normal by this submatrix?

This could be easily achieved with the following code:

normalEyeSpace = vec3(gl_ModelViewMatrix * vec4(gl_Normal,0.0));

So,?gl_NormalMatrix?is just a shortcut to simplify code writing or to optimize it? No, not really. The above line of code will work in some circumstances but not all.

Lets have a look at a potential problem:

;

In the above figure we see a triangle, with a normal and a tangent vectors. The following figure shows what happens when the?modelview?matrix contains a non-uniform scale.

Note: if the scale was uniform, then the direction of the normal would have been preserved, The length would have been affected but this can be easily fixed with a normalization.

In the above figure the?Modelview?matrix was applied to all the vertices as well as to the normal and the result is clearly wrong: the transformed normal is no longer perpendicular to the surface.

We know that a vector can be expressed as the difference between two points. Considering the tangent vector, it can be computed as the difference between the two vertices of the triangle’s edge. If??and??are the vertices that define the edge we know that:

Considering that a vector can be written as a four component tuple with the last component set to zero, we can multiply both sides of the equality with the?Modelview?matrix

This results in

As??and??are the vertices of the transformed triangle,??remains tangent to the edge of the triangle. Hence, the?Modelview?preserves tangents, yet it does not preserve normals.

Considering the same approach used for vector?T, we can find two points??and??such that

The main issue is that the a vector defined through the transformed points,?, does not necessarily remain normal, as shown in the figures above. The normal vector is not defined as a difference between two points, as the tangent vector, it is defined as a vector which is perpendicular to a surface.

So now we know that we can’t apply the?Modelview?in all cases to transform the normal vector. The question is then, what matrix should we apply?

Consider a 3×3 matrix?G, and lets see how this matrix could be computed to properly transform the normal vectors.

We know that, prior to the matrix transformation?T.N?= 0, since the vectors are by definition perpendicular. We also know that after the transformation?N’.T’?must remain equal to zero, since they must remain perpendicular to each other.?T?can be multiplied safely by the upper left 3×3 submatrix of the modelview (T?is a vector, hence the?w?component is zero), let’s call this submatrix?M.

Let’s assume that the matrix?G?is the correct matrix to transform the normal vector.?T. Hence the following equation:

The dot product can be transformed into a product of vectors, therefore:

Note that the transpose of the first vector must be considered since this is required to multiply the vectors. We also know that the transpose of a multiplication is the multiplication of the transposes, hence:

We started by stating that the dot product between?N?and?T?was zero, so if

then we have

Which is exactly what we want. So we can compute?G?based on?M.

Therefore the correct matrix to transform the normal is the transpose of the inverse of the?M?matrix. OpenGL computes this for us in the?gl_NormalMatrix.

In the beginning of this section it was stated that using the?Modelview?matrix would work in some cases. Whenever the 3×3 upper left submatrix of the?Modelview?is orthogonal we have:

This is because with an orthogonal matrix, the transpose is the same as the inverse. So what is an orthogonal matrix? An orthogonal matrix is a matrix where all columns/rows are unit length, and are mutually perpendicular. This implies that when two vectors are multiplied by such a matrix, the angle between them after transformation by an orthogonal matrix is the same as prior to that transformation. Simply put the transformation preserves the angle relation between vectors, hence transformed normals remain perpendicular to tangents! Furthermore it preserves the length of the vectors as well.

So when can we be sure that?M?is orthogonal? When we limit our geometric operations to rotations and translations, i.e. when in the OpenGL application we only use?glRotate?and?glTranslate?and not?glScale. These operations guarantee that?M?is orthogonal. Note:?gluLookAt?also creates an orthogonal matrix!

注:之所以法線不能直接使用UNITY_MATRIX_MV進行變換,是因為法線是向量,具有方向,在進行空間變換的時候,如果發生非等比縮放,方向會發生偏移。為什么呢?拿上面的例子來說,我們可以簡單的把法線和切線當成三角形的兩條邊,顯然,三角形在空間變換的時候,不管是平移,還是旋轉,或者是等比縮放,都不會變形,但是如果非等比縮放,就會發生拉伸。所以法線和切線的夾角也就會發生變化。(而切線在變換前后,方向總是正確的,所以法線方向就不正確了)。

參考:

http://www.lighthouse3d.com/tutorials/glsl-tutorial/the-normal-matrix/

http://forum.Unity3D.com/threads/_object2world-or-unity_matrix_it_mv.112446/

http://www.cnblogs.com/kesalin/archive/2012/12/06/3D_math.html

轉載于:https://www.cnblogs.com/alps/p/7111447.html

總結

以上是生活随笔為你收集整理的UNITY_MATRIX_IT_MV[Matrix]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。