Movatterモバイル変換


[0]ホーム

URL:


On this page

Matrix Compendium Introduction

Originally posted:
Last updated:

Matrix Compendium

Introduction

The primary goal of this article is to consolidate knowledge on transformations in Computer Graphics into a single, comprehensive resource.
Although these concepts are widely available online, they are often presented in disconnected fragments, lacking cohesive explanations of their subtleties. This article seeks to address those gaps and provide a thorough understanding of the topic.

Many real-world problems initially appear simple, but their underlying complexity becomes evident upon closer examination. To explore these challenges comprehensively, we will employ the well-knowndivide and conquer technique. By breaking this intricate problem into smaller sub-problems and addressing each individually, we can create a structured reference guide.
This approach will bring clarity and organization to the challenges often encountered in transformations within computer graphics.

These sub-problems can be categorized from both a mathematical (theoretical) and an implementation (practical) perspective as follows:

  • The order of matrix multiplication: Ensuring operations follow consistent sequencing rules.

  • Thehandedness of three-dimensional Euclidean space: Determining orientation conventions, such as the right-hand rule.

  • The order of basis vectors in a Cartesian coordinate system: Establishing the sequence for defining axes.

  • The storage of matrices in memory as multidimensional arrays: Optimizing memory representation for efficient computations.

Matrix 101

In this article, we will explore matrices and their properties in depth. Before diving into the details, let’s briefly cover a few foundational concepts that are essential for understanding their nuances.

What is a matrix?

In mathematics, a matrix is essentially a rectangular array of numbers organized into rows and columns.
For example, the matrix below has3 rows and5 columns and can be referred to as a3×5\mathbf{3 \times 5} matrix:

[m11m12m13m14m15m21m22m23m24m25m31m32m33m34m35]\begin{array}{c} \begin{bmatrix} m_{11} & m_{12} & m_{13} & m_{14} & m_{15}\\ m_{21} & m_{22} & m_{23} & m_{24} & m_{25}\\ m_{31} & m_{32} & m_{33} & m_{34} & m_{35}\\ \end{bmatrix} \end{array}

Why Are Matrices Important for Computer Graphics?

The answer can be summarized by the following points:

  • They serve as an excellent algebraic tool for representing geometry in a structured way.

  • Transformations such asAffine andProjective in three-dimensional Euclidean space can be represented using4×4\mathbf{4 \times 4} matrices.

  • Concatenation of transformations, or combining two transformations, can be expressed as matrix multiplication.

  • Matrices with one row or column (in other words, row or column vectors) can store mesh vertices.

  • Transformation of mesh vertices from one space to another is, once again, a usage of matrix multiplication.

  • Matrices themselves and operations on them can be efficiently implemented in computer graphics applications.

How Do We Compute Matrix Multiplication?

The algorithm for matrix multiplication is not as straightforward as matrix addition, where corresponding elements from both matrices are added component-wise. Instead, it is slightly more complex and involves combining rows and columns through a series of operations.
To illustrate this concept, consider the following visualization:

_images/mult_anim.gif

The value of each element in matrixC is calculated by multiplying each corresponding entry in the iᵗʰ row of matrixA with the jᵗʰ column of matrixB and summing these products. In essence, this operation is equivalent to performing adot product between the iᵗʰ row of matrixA and the jᵗʰ column of matrixB.

It is important to note:

  1. Matrix multiplication is generallynot commutative—the order of multiplicands in multiplication matters.

  2. For matrix multiplication to be valid, the number ofcolumns in the first matrix (on the left side of the operator) must match the number ofrows in the second matrix.

[a11a12a21a22a31a32a41a42][b11b12b13b21b22b23]=[c11c12c13c21c22c23c31c32c33c41c42c43]\begin{array}{c} \begin{bmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \\ a_{31} & a_{32} \\ a_{41} & a_{42} \\ \end{bmatrix} * \begin{bmatrix} b_{11} & b_{12} & b_{13}\\ b_{21} & b_{22} & b_{23}\\ \end{bmatrix} = \begin{bmatrix} c_{11} & c_{12} & c_{13}\\ c_{21} & c_{22} & c_{23}\\ c_{31} & c_{32} & c_{33}\\ c_{41} & c_{42} & c_{43}\\ \end{bmatrix} \end{array}

Divide and Conquer

Once we have completed the preliminary explanations, we can shift our attention to the core of this article.

The Order of Matrix Multiplication

Now that we understand matrix multiplication, we can discuss its order. One of the key—yet often overlooked—aspects of transformations in computer graphics is that matrix multiplication isgenerally non-commutative.
We are accustomed to the fact that multiplication of real numbers is commutative. Therefore, when we learn about matrices, it is surprising—and often leads to errors in practice—that matrix multiplication is non-commutative:

ABBA\begin{array}{c} \mathbf{A} * \mathbf{B} \neq \mathbf{B} * \mathbf{A} \end{array}

whereAA andBB are matrices.

To minimize challenges in practice, two distinct approaches—or conventions—have emerged, each offering a method for ensuring consistent and correct application of matrix multiplication.
In computer graphics, these conventions are referred to as:

  • Pre-multiplication Transformation

  • Post-multiplication Transformation

It is worth noting that the terminology of pre- and post-multiplication is used by some authors but not universally.
For example, in linear algebra, vectors are typically treated as column vectors when solving systems of equations, leading to a preference for post-multiplication order in textbooks.

Matrix Multiplication Order and Transformations in Three-Dimensional Euclidean Space

In computer graphics applications, transformations such as translation, rotation, scaling, and shearing are combined to create realistic virtual worlds. These transformations are represented using4×44 \times 4 matrices, and combining them is equivalent to multiplying matrices.
It is crucial to choose and apply the correct order consistently to achieve the desired result.

While matrix multiplication is non-commutative, it remains associative:

(AB)C=A(BC)(\mathbf{A} * \mathbf{B}) * \mathbf{C} = \mathbf{A} * (\mathbf{B} * \mathbf{C})

In the examples below, parentheses are used solely to indicate the order in which transformations are combined.

Let’s describe the problem of matrix multiplication order for transformation concatenation using the following example:

Z=ABCD\begin{array}{c} \mathbf{Z} = \mathbf{A} * \mathbf{B} * \mathbf{C} * \mathbf{D} \end{array}

whereAA,BB,CC,DD,ZZ are matrices.

Parentheses are helpful to clearly indicate the sequence (order) of operations. In mathematics, multiplication is typically assumed to proceed from left to right.

The differences between the two conventions are summarized in the table below:

Post-multiplicationPre-multiplication
Order of operationsZ=ABCD=A(B(CD))\mathbf{Z} = \mathbf{A} \cdot \mathbf{B} \cdot \mathbf{C} \cdot \mathbf{D} =\mathbf{A} \cdot (\mathbf{B} \cdot (\mathbf{C} \cdot \mathbf{D}))Z=ABCD=((AB)C)D\mathbf{Z} = \mathbf{A} \cdot \mathbf{B} \cdot \mathbf{C} \cdot \mathbf{D} =((\mathbf{A} \cdot \mathbf{B}) \cdot \mathbf{C}) \cdot \mathbf{D}
Transforming a vectorVw=MVc\vec{V_w} = \mathbf{M} \cdot \vec{V_c}Vw=VcM\vec{V_w} = \vec{V_c} \cdot \mathbf{M}
Vector representation[xyzw]=[m11m12m13m14m21m22m23m24m31m32m33m34m41m42m43m44][v1v2v3v4]\begin{bmatrix} x \\ y \\ z \\ w \end{bmatrix} = \begin{bmatrix}m_{11} & m_{12} & m_{13} & m_{14} \\m_{21} & m_{22} & m_{23} & m_{24} \\m_{31} & m_{32} & m_{33} & m_{34} \\m_{41} & m_{42} & m_{43} & m_{44}\end{bmatrix}\cdot\begin{bmatrix}v_1 \\ v_2 \\ v_3 \\ v_4\end{bmatrix}[xyzw]=[v1v2v3v4][m11m21m31m41m12m22m32m42m13m23m33m43m14m24m34m44]\begin{bmatrix}x & y & z & w\end{bmatrix} = \begin{bmatrix}v_1 & v_2 & v_3 & v_4\end{bmatrix}\cdot\begin{bmatrix}m_{11} & m_{21} & m_{31} & m_{41} \\m_{12} & m_{22} & m_{32} & m_{42} \\m_{13} & m_{23} & m_{33} & m_{43} \\m_{14} & m_{24} & m_{34} & m_{44}\end{bmatrix}
Final Transformation MatrixMf=MpMvMm\mathbf{M_f} = \color{magenta}\mathbf{M_p}\color{default} \cdot\color{cyan}\mathbf{M_v}\color{default} \cdot\color{yellow}\mathbf{M_m}\color{default}Mf=MmMvMp\mathbf{M_f} = \color{yellow}\mathbf{M_m}\color{default} \cdot\color{cyan}\mathbf{M_v}\color{default} \cdot\color{magenta}\mathbf{M_p}\color{default}
World Matrix CompositionMw=MaMl\mathbf{M_w} = \color{Violet}\mathbf{M_a}\color{default} \cdot\color{SpringGreen}\mathbf{M_l}\color{default}Mw=MlMa\mathbf{M_w} = \color{SpringGreen}\mathbf{M_l}\color{default} \cdot\color{Violet}\mathbf{M_a}\color{default}
Local Transformation MatrixMl=MtMrMs\color{SpringGreen}\mathbf{M_l}\color{default} =\color{red}\mathbf{M_t}\color{default} \cdot\color{green}\mathbf{M_r}\color{default} \cdot\color{RoyalBlue}\mathbf{M_s}\color{default}Ml=MsMrMt\color{SpringGreen}\mathbf{M_l}\color{default} =\color{RoyalBlue}\mathbf{M_s}\color{default} \cdot\color{green}\mathbf{M_r}\color{default} \cdot\color{red}\mathbf{M_t}\color{default}
Local Transformation MatrixMl=MtMrMhMs\color{SpringGreen}\mathbf{M_l}\color{default} =\color{red}\mathbf{M_t}\color{default} \cdot\color{green}\mathbf{M_r}\color{default} \cdot\color{grey}\mathbf{M_h}\color{default} \cdot\color{RoyalBlue}\mathbf{M_s}\color{default}Ml=MsMhMrMt\color{SpringGreen}\mathbf{M_l}\color{default} =\color{RoyalBlue}\mathbf{M_s}\color{default} \cdot\color{grey}\mathbf{M_h}\color{default} \cdot\color{green}\mathbf{M_r}\color{default} \cdot\color{red}\mathbf{M_t}\color{default}
Impact of conventionTransformations composedright-to-leftTransformations composedleft-to-right
Impact of conventionPreferred matrix storage incolumn-major layoutPreferred matrix storage inrow-major layout
Impact of conventionMesh vertices treated ascolumn vectorsMesh vertices treated asrow vectors

Where:
Vw\vec{V_w} = Transformed vector in another space.
Vc\vec{V_c} = Transformed vector in original space.
M\mathbf{M} = Transform matrix.
Mf\mathbf{M_f} = Final transformation matrix.
Mm\color{yellow}\mathbf{M_m}\color{default}= Model transformation matrix (transforms from local model space to global world space).
Mv\color{cyan}\mathbf{M_v}\color{default}= View matrix (transforms from world space to camera space).
Mp\color{magenta}\mathbf{M_p}\color{default}= Projection matrix (transforms from camera space to clipping space).
Mw\mathbf{M_w} = World transformation matrix.
Ml\color{SpringGreen}\mathbf{M_l}\color{default}= Current local transformation matrix.
Ma\color{Violet}\mathbf{M_a}\color{default}= Transformation matrix of the parent node.
Ms\color{RoyalBlue}\mathbf{M_s}\color{default}= Scaling matrix.
Mr\color{green}\mathbf{M_r}\color{default}= Rotation matrix.
Mt\color{red}\mathbf{M_t}\color{default}= Translation matrix.
Mh\color{grey}\mathbf{M_h}\color{default}= Shear matrix.

TheHandedness of Three-Dimensional Euclidean Space

Before discussing the topic of the orientation of three-dimensional Euclidean space, one more issue should be mentioned and described: the “Up Direction” axial convention.

Three-Dimensional Cartesian Coordinate System: “Up Direction”

Mathematically, no axis is inherently designated as theUp Direction in three-dimensional Euclidean space.
However, in 3D applications, two conventions have emerged over the years:

  • ZZ-Axis as “Up Direction”

    This convention is particularly useful in fields such as architecture. When theworking space is a plane representing, for example, the Earth’s surface, the two main working directions are theXX-Axis andYY-Axis, while theZZ-Axis represents elevation, or the “Up Direction.”

    _images/Z-Up.jpg

  • YY-Axis as “Up Direction”

    In this convention, theworking plane corresponds to the monitor screen. TheXX-Axis andYY-Axis represent the width and height of the screen, respectively, while theZZ-Axis represents depth. This setup aligns with our everyday perception of the world, such as in first-person shooter (FPS) games, where theYY-Axis represents the “Up Direction.”

    _images/Y-Up.jpg

Cross Product in Three-Dimensional Euclidean Space

In computer graphics, particularly in three-dimensional Euclidean space, the cross product is a highly useful and common operation. The cross product of two non-collinear vectors results in another vector that is perpendicular to both original vectors.
This operation introduces ambiguity because the direction of the resulting vector does not have a unique solution—it could point in two equally valid directions. To resolve this ambiguity, we select anorientation (orhandedness) for the three-dimensional Euclidean space. By making this choice, we designate one cross-product direction as the preferred solution.

_images/cross_ambi.gif

To get a unique and consistent result, we use either theright-hand rule or theleft-hand rule.
It is worth mentioning that in mathematics and physics, the right-hand orientation is the most commonly used. This orientation is applied to determine directions in magnetic fields, electromagnetic fields, and enantiomers in chemistry.

Left-Hand RuleRight-Hand Rule
_images/CrossLH.png_images/CrossRH.png

Theright-hand rule andleft-hand rule can be described as follows:
Let the straightened index finger of the chosen hand (right or left) point in the direction of the first vector (a\vec{a}), and let the bent middle finger point in the direction of the second vector (b\vec{b}). Finally, the extended thumb will indicate the direction of the cross-product vectora×b\vec{a} \times \vec{b}.

To determine the directions of theXX,YY, andZZ axes in three-dimensional Euclidean space, replace the first vector with the direction of theXX-Axis and the second vector with the direction of theYY-Axis. The thumb will then indicate the direction of theZZ-Axis.

Using this method, we can designate a three-dimensional Euclidean space with the desiredhandedness (orientation). The orientations,right-hand orleft-hand, can be summarized in the table below (if applicable).

HandednessLeft-Hand RuleRight-Hand Rule
Y-Up_images/Y-Up-LH.png_images/Y-Up-RH.png
Z-Up_images/Z-Up-LH.png_images/Z-Up-RH.png

Importance of Choosing the Handedness

Choosing the handedness is crucial as it determines not only the direction of the cross-product vector but also:

  • The orientation of surface normal vectors.

  • The direction in which points rotate around an axis.

  • The order of vertices in triangle meshes.

Left-Hand RuleRight-Hand Rule
_images/PlaneDown.png_images/PlaneUp.png
_images/OrderCW.png_images/OrderCCW.png

Anticommutativity of Cross Product

Another key property of the cross product of two non-collinear vectors is anticommutativity:

a×b=b×a\begin{array}{c} \vec{a} \times \vec{b} = - \vec{b} \times \vec{a} \end{array}

If you need to fix a rendering error by reversing the result of a cross product, keep in mind that you are not simply adding a *negative sign* to the vector. Instead, you are altering the handedness of your three-dimensional Euclidean space.

Left-Hand RuleRight-Hand Rule
_images/cross_LH.gif_images/cross_RH.gif

The Order of Basis Vectors in a Cartesian Coordinate System

This topic should be introduced prior to the concept ofhandedness in Euclidean space, as the two are closely related. It is usually covered earlier in linear algebra classes. However, describing it now will make it easier to understand.

The concept ofbasis vectors often remains hidden in the shadows of linear algebra textbooks, and its significance is frequently overlooked, despite being fundamental to linear algebra and vector spaces.
For example, in three-dimensional Euclidean space, the followingbasis vectors:

e0=(1,0,0)e1=(0,1,0)e2=(0,0,1)\vec{e_0} = (1,0,0) \\ \vec{e_1} = (0,1,0) \\ \vec{e_2} = (0,0,1) \\

form thebuilding blocks of the Euclidean space. They allow any vector in this space to be described in terms of thesebasis vectors.

However, defining the basis vectors is only part of the process—it is also necessary to determine their order, specifying which vector is designated as the first, second, and third. For example:

e0,e1,e2{\vec{e_0},\vec{e_1},\vec{e_2}}e0,e2,e1{\vec{e_0},\vec{e_2},\vec{e_1}}
_images/order_XYZ.gif_images/order_XZY.gif

The order of the basis vectors is important because, while coordinate systems defined by different orders may appear similar, they are not the same and differ in subtle ways:

{e0,e1,e2}{e0,e2,e1}\{\vec{e_0},\vec{e_1},\vec{e_2}\} \neq \{\vec{e_0},\vec{e_2},\vec{e_1}\}

When the basis vectors and their order are determined, we establish the Cartesian coordinate system. This allows us to uniquely determine the position of points in space and define the Positive Direction—the direction of rotation when increasing the angle of rotation.

From a mathematical and computational perspective, there is no universally better or worse ordering of basis vectors. However, physicists consistently use the right-hand rule, a convention based on the same principle as the cross-product vector direction. This rule eliminates ambiguities, facilitates collaboration, and ensures coherence in calculations across different contributors.

Unfortunately, the absence of a standardized framework in computer graphics increases the likelihood of errors. This article aims to highlight the importance of addressing this issue.

Positive Direction in Two-Dimensional Euclidean Space

The concept ofPositive Direction refers to the direction of rotation established by starting from thefirst chosen basis vector (or axis of the coordinate system) and moving in the direction of thesecond basis vector.

Visually, this can be easily explained in two-dimensional Euclidean space, as shown in the table below:

Basis Vector Ordere0,e1{\vec{e_0},\vec{e_1}} orXYX \rightarrow YBasis Vector Ordere1,e0{\vec{e_1},\vec{e_0}} orYXY \rightarrow X
Counterclockwise rotationClockwise rotation
From theXX-axis towards theYY-axisFrom theYY-axis towards theXX-axis
_images/OrderXY.png_images/OrderYX.png

This demonstrates why the order of basis vectors matters.

Positive Direction and Rotation Matrices

To describe a rotation in two- or three-dimensional Euclidean space, a rotation matrix is commonly used. This matrix is then applied to rotate a vector (or a point treated as a vector) by a specified angle.
The rotation is achieved by multiplying the vector by the matrix. Matrix multiplication is not commutative, as we’ve seen, so two conventions exist for rotation: pre-multiplication and post-multiplication.

The order of basis vectors plays a nuanced role in defining the rotation. For example, the same rotation matrix:

R=[cos(ϕ)sin(ϕ)sin(ϕ)cos(ϕ)]R = \begin{bmatrix} \cos(\phi) & -\sin(\phi)\\ \sin(\phi) & \cos(\phi)\\ \end{bmatrix}

depending on whether it is used in pre- or post-multiplication, determines the Positive Direction of rotation for different orders of basis vectors.
In the two-dimensional case, this relates toe0,e1{\vec{e_0},\vec{e_1}} ore1,e0{\vec{e_1},\vec{e_0}}.

Post-multiplication conventionv=Rvv’ = R * vPre-multiplication conventionv=vRv’ = v * R
Counterclockwise rotationClockwise rotation
Basis Vector Ordere0,e1{\vec{e_0},\vec{e_1}} orXYX \rightarrow YBasis Vector Ordere1,e0{\vec{e_1},\vec{e_0}} orYXY \rightarrow X
_images/rot_ccw.gif_images/rot_cw.gif

Ensuring Coherence in Basis Vector Order and Rotation

Maintaining coherence in the concept of the order of basis vectors is critical when determining the position of a point in space and the unique Positive Direction of rotation.
To ensure coherence, the specific form of the rotation matrix must correspond to a particular order of basis vectors, along with the chosen matrix multiplication convention.

All of these options can be summarized in the table below:

Basis Vector Ordere0,e1{\vec{e_0},\vec{e_1}} orXYX \rightarrow YBasis Vector Ordere1,e0{\vec{e_1},\vec{e_0}} orYXY \rightarrow X
Post-multiplication convention[cos(ϕ)sin(ϕ)sin(ϕ)cos(ϕ)]\begin{bmatrix}\cos(\phi) & \color{red}-\color{default}\sin(\phi)\sin(\phi) & \cos(\phi)\end{bmatrix}[cos(ϕ)sin(ϕ)sin(ϕ)cos(ϕ)]\begin{bmatrix}\cos(\phi) & \sin(\phi)\color{red}-\color{default}\sin(\phi) & \cos(\phi)\end{bmatrix}
Pre-multiplication convention[cos(ϕ)sin(ϕ)sin(ϕ)cos(ϕ)]\begin{bmatrix}\cos(\phi) & \sin(\phi)\color{red}-\color{default}\sin(\phi) & \cos(\phi)\end{bmatrix}[cos(ϕ)sin(ϕ)sin(ϕ)cos(ϕ)]\begin{bmatrix}\cos(\phi) & \color{red}-\color{default}\sin(\phi)\sin(\phi) & \cos(\phi)\end{bmatrix}

Positive Direction in Three-Dimensional Euclidean Space

To determine the Positive Rotation, in three-Dimensional Euclidean Space we can use a hand rule similar to the one used for the cross-product.

Theright-hand rule andleft-hand rule in this context can be described as follows:

Bent fingers point in the direction of the Positive Direction, and your thumb indicates the axis of rotation
or
Point your thumb in the direction of the axis of rotation, and your bent fingers will indicate the Positive Direction.

Let us illustrate these rules using the following table:

Left-Hand Axis of RotationRight-Hand Axis of Rotation
imageimage

In three-dimensional Euclidean space, we encounter several possible permutations of basis vector orders. Fortunately, these permutations can be grouped into two groups of basis vector orders:

In the table below, I aim to demonstrate why the topic of the order of basis vectors—and, consequently, the Positive Direction of rotation—can appear complex and challenging to comprehend.

Left-Hand RuleRight-Hand Rule
(X,Y,Z)(X, Y, Z)(X,Z,Y)(X, Z, Y)(X,Y,Z)(X, Y, Z)(X,Z,Y)(X, Z, Y)
YY-Up_images/YUp_LH_XYZ.png_images/YUp_LH_XZY.png_images/YUp_RH_XYZ.png_images/YUp_RH_XZY.png
ZZ-Up_images/ZUp_LH_XYZ.png_images/ZUp_LH_XZY.png_images/ZUp_RH_XYZ.png_images/ZUp_RH_XZY.png

The variety of possible use cases increases the likelihood of making mistakes. How can we summarize the table above? After analyzing each case, the hand used to determine the order of the base vectors (and thus the Positive Direction of rotation), as well as the direction of the vector product, varies. In some cases, different hands are required, while in others, the same hand is used. The table below provides a summary of these cases:

Basis Vector Order Group:(X,Y,Z)(X, Y, Z)Basis Vector Order Group:(X,Z,Y)(X, Z, Y)
Right-Hand Rule for Cross-ProductThe SAME hand rule is used for both cross-product direction and Positive DirectionThe OPPOSITE hand rule is used for cross-product direction and Positive Direction
Left-Hand Rule for Cross-ProductThe SAME hand rule is used for both cross-product direction and Positive DirectionThe OPPOSITE hand rule is used for cross-product direction and Positive Direction

Maintaining coherence in basis vector order is essential for determining point positions in space and the Positive Direction of rotations. Only the basis vector order from the group(X,Y,Z)(X, Y, Z) satisfies these criteria.

Finally, the Positive Direction in three-dimensional Euclidean space are illustrated in the table below:

Left-Hand RuleRight-Hand Rule
YY-Up_images/Rot_YUp_LH_XYZ.gif_images/Rot_YUp_RH_XYZ.gif
ZZ-Up_images/Rot_ZUp_LH_XYZ.gif_images/Rot_ZUp_RH_XYZ.gif

Basis Vector Order and Rotation Systems

Consider this: If you create a model in aYY-Up left-handed coordinate system but render it in aZZ-Up left-handed coordinate system, swapping theYY andZZ coordinates may seem like a simple fix.
However, this adjustment implicitly alters elements like plane normal vectors, triangle mesh winding orders, and associated animation data due to changes in Positive Direction and basis vector order.

Positive Direction and Quaternions

The order of basis vectors also affects quaternions. When W. R. Hamilton invented quaternions to describe rotations in three-dimensional Euclidean space, he defined them asQ=a+bi+cj+dkQ = a + bi + cj + dk and established dependencies between the imaginary components:ij=kij = k,jk=ijk = i,ki=jki = j, andijk=1ijk = -1. When quaternions are defined using these rules, the Positive Direction of rotation is determined by theright-hand rule. In computer graphics, however, there are applications that use theleft-hand rule to determine the Positive Direction. This raises the question: how should quaternions defined in this manner be handled?
The convention proposed by M.D. Shuster does not change the fundamental definition of the quaternion itself but modifies its dependencies on the imaginary components. This approach differs slightly from the quaternion definitions typically found in mathematics textbooks. Notably, Shuster’s definition is employed by NASA’s Jet Propulsion Laboratory and, in computer graphics, within the Microsoft DirectX Math Library.

The differences between Hamilton’s and Shuster’s quaternion definitions are summarized in the following table:

Hamilton’s DefinitionShuster’s Definition
Imaginary Components Dependenciesij=k jk=i ki=j ijk=1ij = k\ jk = i\ ki = j\ ijk = -1ij=k jk=i ki=j ijk=1ij = -k\ jk = -i\ ki = -j\ ijk = 1
Positive DirectionDetermined byright-hand ruleDetermined byleft-hand rule
Matrix Multiplication OrderPost-multiplicationPre-multiplication
“Sandwich” Product Orderv=QvQ1v’ = Q v Q^{-1}v=Q1vQv’ = Q^{-1} v Q
Rotation MatrixR=[12(Qy2+Qz2)2(QxQyQzQw)2(QxQz+QyQw) 2(QxQy+QzQw)12(Qx2+Qz2)2(QyQzQxQw) 2(QxQzQyQw)2(QyQz+QxQw)12(Qx2+Qy2)]R = \begin{bmatrix}1 - 2(Q_y^2 + Q_z^2) & 2(Q_xQ_y \color{red}-\color{default} Q_zQ_w) & 2(Q_xQ_z + Q_yQ_w)\ 2(Q_xQ_y + Q_zQ_w) & 1 - 2(Q_x^2 + Q_z^2) & 2(Q_yQ_z \color{red}-\color{default} Q_xQ_w)\ 2(Q_xQ_z \color{red}-\color{default} Q_yQ_w) & 2(Q_yQ_z + Q_xQ_w) & 1 - 2(Q_x^2 + Q_y^2)\end{bmatrix}R=[12(Qy2+Qz2)2(QxQy+QzQw)2(QxQzQyQw) 2(QxQyQzQw)12(Qx2+Qz2)2(QyQz+QxQw) 2(QxQz+QyQw)2(QyQzQxQw)12(Qx2+Qy2)]R = \begin{bmatrix}1 - 2(Q_y^2 + Q_z^2) & 2(Q_xQ_y + Q_zQ_w) & 2(Q_xQ_z \color{red}-\color{default} Q_yQ_w)\ 2(Q_xQ_y \color{red}-\color{default} Q_zQ_w) & 1 - 2(Q_x^2 + Q_z^2) & 2(Q_yQ_z + Q_xQ_w)\ 2(Q_xQ_z + Q_yQ_w) & 2(Q_yQ_z \color{red}-\color{default} Q_xQ_w) & 1 - 2(Q_x^2 + Q_y^2)\end{bmatrix}

Handedness in Computer Graphics Applications

To summarize Positive Direction concepts, here’s a table of applications (game engines or software tools for animations or models) that utilize different three-dimensional space orientations and specify the Up axis:

OrientationLeft-Hand RuleRight-Hand Rule
YY-Up

LightWave

ZBrush

Cinema 4D

Unity

Autodesk Maya

Modo

Houdini 3D Animation Tool

Substance Painter

Marmoset Toolbag

Godot

OGRE

ZZ-Up

Unreal Engine*

Open 3D Engine

Autodesk 3ds Max

Blender

SketchUp

Autodesk AutoCAD

CRYENGINE

UNIGINE

Special Case: Unreal Engine

Unreal Engine uses both hand rules depending on the axis of rotation. For example:

  • XX andYY-Axis:Right-hand rule

  • ZZ-Axis:Left-hand rule

image

The Storage of Matrices in Memory as Multidimensional Arrays

We now turn to a strictly implementation-related topic.
From the matrix definition, a matrix is a two-dimensional mathematical object (it has row and column dimensions), but computer memory operates linearly as a one-dimensional array.

_images/memory.png

Representing Matrices in Computer Memory

How can we represent this matrix in computer memory?
A common solution is to use multidimensional arrays. These arrays can be mapped to computer memory in different ways, each offering distinct advantages and disadvantages.
The simplest and most widely used methods are therow-major andcolumn-major conventions, where matrices are stored row by row or column by column, respectively.

Row-MajorColumn-Major
Example3×53\times5 Matrix_images/OrderRow.png_images/OrderColumn.png
Example4×44\times4 Matrix_images/memory_row_anim.gif_images/memory_col_anim.gif

We have two conventions for storing matrices in memory, and each programming language must decide which one to adopt for its multidimensional array representation.
The following table summarizes how some popular programming languages implement these conventions:

Storage OrderProgramming Languages
Row Layout Order

C

C++

Python (NumPy)

Java

Rust

HLSL (by default or withrow_major modifier)

GLSL (withlayout(row_major) qualifier)

Column Layout Order

Fortran

Matlab

Julia

HLSL (withcolumn_major modifier)

GLSL (by default or withlayout(column_major) qualifier)

The majority of widely used languages favorrow-major order, while those focused on numerical or scientific computations often prioritizecolumn-major order.

The Storage of Matrices as Transformations

Data storage conventions are inevitably linked to transformations.
For example, in a translation matrix, the translation vector is stored in either the third row or the third column, depending on the multiplication order.

Pre-MultiplicationPost-Multiplication
_images/PRE_MAT.png_images/POST_MAT.png

Two multiplication orders and two storage conventions yield four ways to store a translation matrix:

|Pre-Multiplication |Pre-Multiplication |Post-Multiplication |Post-Multiplication |

Row-MajorColumn-MajorRow-MajorColumn-Major
_images/PRE_ROW.png_images/PRE_COL.png_images/POST_ROW.png_images/POST_COL.png

For performance reasons, it is better to read or write memory elements that are adjacent.
As a result, the translation vector should be stored using the convention that allows for this. This may explain why applications that store matrices inrow-major order often prefer thepre-multiplication convention, while those storing matrices incolumn-major order tend to favor thepost-multiplication convention.

But what can we do if, for some reason, we need to use thepost-multiplication convention, and we don’t want to store matrices incolumn-major order?
There is a way—though somewhat hacky—but it is possible.
We can reinterpret the multidimensional array indices in a different order.
By doing this, in C/C++, we canpretend that the matrix is stored in column-major order rather than row-major order.

Both approaches to storing multidimensional arrays are summarized in the following table:

[Row][Column] Order[Column][Row] Order
foo[X][Y] is interpreted asX×Y\mathbf{X \times Y} matrixfoo[X][Y] is interpreted asY×X\mathbf{Y \times X} matrix
To access matrix elements,
specify the desiredrow using the first square bracket
and the desiredcolumn using the second square bracket
To access matrix elements,
specify the desiredcolumn using the first square bracket
Therows of a matrix correspond directly to therows in a multidimensional arrayThecolumns of a matrix correspond to therows in a multidimensional array
More intuitive for mathematicians, as it aligns closely with the matrix definitionBy doing this, we canpretend that matrices are being stored in column-major order
imageimage

The Storage of Matrices in HLSL and GLSL

HLSL and GLSL shader languages are independent from the perspective of matrix multiplication and matrix storage. Similarly, hardware and Graphics APIs, such as DirectX® and Vulkan®, are also independent of these conventions and support various possibilities. However, their default behavior is defined by older API versions.

This independence is evident in how vectors and matrices interact. When a vector is multiplied by a matrix,vp=vm\vec{v_p} = \vec{v} * \mathbf{m}, the vectorv\vec{v} is treated as a row vector. Conversely, when the matrix is multiplied by the vector,vp=mv\vec{v_p} = \mathbf{m} * \vec{v}, the vectorv\vec{v} is treated as a column vector.

Graphics APIs and implicit coordinate systemhandedness

When 3D Graphics APIs were first introduced, they adhered to specific coordinate system conventions:

  1. OpenGL®: Right-hand coordinate system, and a post matrix multiplication convention.

  2. DirectX®: Left-hand coordinate system, and a pre matrix multiplication convention.

With the evolution of GPU hardware and graphics APIs, these conventions have become less rigid. Today, most APIs are agnostic to the coordinate system and multiplicative order, with two notable exceptions. The API must ultimately commit to (and cannot be overridden by the user) thehandedness of the two and three-dimensional Euclidean space in the following contexts:

  1. Clipping Space (normalized device coordinate (NDC) space or homogeneous screen space).
APIClipping Space
DirectX®XX-Axis points to the right,YY-Axis points up,ZZ-Axis points into the screen,ZZ in the range[0,1][0,1]
Vulkan®XX-Axis points to the right,YY-Axis points down,ZZ-Axis points into the screen,ZZ in the range[0,1][0,1]
OpenGL®XX-Axis points to the right,YY-Axis points up,ZZ-Axis points into the screen,ZZ in the range[1,1][-1,1]
MetalXX-Axis points to the right,YY-Axis points up,ZZ-Axis points into the screen,ZZ in the range[0,1][0,1]
WebGPUXX-Axis points to the right,YY-Axis points up,ZZ-Axis points into the screen,ZZ in the range[1,1][-1,1]
WebGL™XX-Axis points to the right,YY-Axis points up,ZZ-Axis points into the screen,ZZ in the range[0,1][0,1]
  1. Texture space
APITexture space
DirectX®origin Top-Left corner,XX-Axis points to the right,YY-Axis points down
Vulkan®origin Top-Left corner,XX-Axis points to the right,YY-Axis points down
OpenGL®origin Bottom-Left corner,XX-Axis points to the right,YY-Axis points up (by default)
Metalorigin Top-Left corner,XX-Axis points to the right,YY-Axis points down
WebGPUorigin Top-Left corner,XX-Axis points to the right,YY-Axis points down
WebGL™origin Bottom-Left corner,XX-Axis points to the right,YY-Axis points up

Transformation matrices

The above considerations—namely, the non-commutative nature of matrix multiplication and the anticommutativity of a vector’s cross product—have important consequences for the four alternative methods of constructing a 3D transformation as a 4×4 matrix. Each of these alternatives is described in detail in the sections below.

Tips on the Above Conventions:

  1. Transposing the entire4×4 matrix willonly change the pre- and post-multiplication order (without altering the coordinate system’s “handedness” or the order of the basis vectors).

  2. Transposing just theupper-left 3×3 matrix willonly change the order of the basis vectors (without affecting the pre- and post-multiplication order).

How to Detect LH/RH Row/Column-Major Pre/Post Multiplication Conventions

The specific convention used in an application may not be immediately apparent. Answering the following questions can help identify it:

  1. Translation Matrix Construction: Examine how the components of the translation vector (XX,YY,ZZ) are stored in memory. Are they stored adjacent to each other (1a) or separated (1b)?

  2. Order of Transformations: Determine the sequence in which transformations (Scale,Rotation, andTranslation) are applied. Is the composition executed asTRST \cdot R \cdot S (2a) orSRTS \cdot R \cdot T (2b)? Similarly, isMatrix-Vector multiplication computed asMVM \cdot V (2a) orVMV \cdot M (2b)?

  3. Rotation Storage: Check how rotation around theXX-Axis orZZ-Axis is represented in memory. Does the first stored element correspond tosin-\sin (3a) orsin\sin (3b)? For rotation around theYY-Axis, is the first stored elementsin\sin (3a) orsin-\sin (3b)?

  4. Handedness of Coordinate System: Use the “hand rule” to determine the coordinate system. For the left hand, the straightened index finger points along theXX-Axis, the bent middle finger along theYY-Axis, and the extended thumb along theZZ-Axis (4a). For the right hand, the corresponding directions are (4b).

With answers to these questions, the conventions in use can be identified using the table below.

Question 1Question 2Question 3Question 4\rightarrowConvention
1a2a3a4a\rightarrowPost-multiplication, Column-Major,X,Z,YX, Z, Y, Left-handed
1b2a3a4a\rightarrowPost-multiplication, Row-Major,X,Y,ZX, Y, Z, Left-handed
1a2b3a4a\rightarrowPre-multiplication, Row-Major,X,Y,ZX, Y, Z, Left-handed
1b2b3a4a\rightarrowPre-multiplication, Column-Major,X,Z,YX, Z, Y, Left-handed
1a2a3b4a\rightarrowPost-multiplication, Column-Major,X,Z,YX, Z, Y, Left-handed
1b2a3b4a\rightarrowPost-multiplication, Row-Major,X,Y,ZX, Y, Z, Left-handed
1a2b3b4a\rightarrowPre-multiplication, Row-Major,X,Y,ZX, Y, Z, Left-handed
1b2b3b4a\rightarrowPre-multiplication, Column-Major,X,Z,YX, Z, Y, Left-handed
1a2a3a4b\rightarrowPost-multiplication, Column-Major,X,Z,YX, Z, Y, Right-handed
1b2a3a4b\rightarrowPost-multiplication, Row-Major,X,Y,ZX, Y, Z, Right-handed
1a2b3a4b\rightarrowPre-multiplication, Row-Major,X,Y,ZX, Y, Z, Right-handed
1b2b3a4b\rightarrowPre-multiplication, Column-Major,X,Z,YX, Z, Y, Right-handed
1a2a3b4b\rightarrowPost-multiplication, Column-Major,X,Z,YX, Z, Y, Right-handed
1b2a3b4b\rightarrowPost-multiplication, Row-Major,X,Y,ZX, Y, Z, Right-handed
1a2b3b4b\rightarrowPre-multiplication, Row-Major,X,Y,ZX, Y, Z, Right-handed
1b2b3b4b\rightarrowPre-multiplication, Column-Major,X,Z,YX, Z, Y, Right-handed

Related software

Related news and technical articles

HIP Threads: GPU power for teams without GPU experts
HIP Threads: GPU power for teams without GPU experts
HIP Threads lets C++ teams eliminate CPU hotspots by running familiar multithreaded code on AMD GPUs, no kernel rewrites or GPU expertise required, delivering real speedups in days.
Dyson Sphere Program - new multithreading dev log & full AMD Ryzen Threadripper PRO breakdown
Dyson Sphere Program - new multithreading dev log & full AMD Ryzen Threadripper PRO breakdown
Youthcat Games overhauled the Dyson Sphere Program game's multithreading system, boosting performance by up to 88% through custom core binding, dynamic task allocation, and enhanced thread synchronization.
AMD FSR™ Redstone expands with the latest AMD FSR™ SDK 2.1
AMD FSR™ Redstone expands with the latest AMD FSR™ SDK 2.1
AMD FSR 'Redstone' SDK 2.1 enables developers to integrate FSR features into games with easy-to-use APIs and access to advanced neural rendering technologies.
Training an X-ARM 5 robotic arm with AMD Schola and Unreal Engine
Training an X-ARM 5 robotic arm with AMD Schola and Unreal Engine
Train a robot arm with reinforcement learning in AMD Schola using Unreal® Engine, progressively increasing task complexity to adapt to changing conditions.
Announcing AMD Schola v2: Next-generation reinforcement learning for Unreal Engine
Announcing AMD Schola v2: Next-generation reinforcement learning for Unreal Engine
AMD Schola v2 is a major update to the open-source reinforcement learning plugin for Unreal® Engine 5, offering significant improvements in capabilities, performance, and ease of use for training and deploying AI agents.
Introducing AMD GI-1.2 with multibounce indirect real-time rendering
Introducing AMD GI-1.2 with multibounce indirect real-time rendering
AMD GI-1.2, our real-time Global Illumination solution, is available now as part of the AMD Capsaicin Framework v1.3.
ONNX and DirectML execution provider guide - part 1
ONNX and DirectML execution provider guide - part 1
Learn how to optimize neural network inference on AMD hardware using the ONNX Runtime with the DirectML execution provider and DirectX 12 in the first part of our guide.
ONNX and DirectML execution provider guide - part 2
ONNX and DirectML execution provider guide - part 2
Learn how to optimize neural network inference on AMD hardware using the ONNX Runtime with the DirectML execution provider and DirectX 12 in the second part of our guide.

Related videos


[8]ページ先頭

©2009-2026 Movatter.jp