Starllow
HomeBlogShowcase
ProgrammingAug 3, 2025

WebGL 编程中的数学知识之矩阵

介绍矩阵的定义、表示方式、运算规则等,以及在 WebGL 编程中的用法。

MathmaticWebGLProgramming

什么是矩阵

矩阵就是一个按照长方形排列的数表,本质上就是一个二维数组。

将m x n 个元素按 m 行,n 列的方式排列,可用下面的方式表示:

A=[a11a12⋯a1na21a22⋯a2n⋮⋮⋱⋮am1am2⋯amn]\mathbf{A} = \begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \end{bmatrix}A=​a11​a21​⋮am1​​a12​a22​⋮am2​​⋯⋯⋱⋯​a1n​a2n​⋮amn​​​

常见的有:2x2,3x3,4x4等。

矩阵可用来表示线性变换,图形学中的平移、缩放、旋转、投影、相机视角等变换,全靠矩阵。

矩阵的加减法

矩阵加减法计算是在矩阵对应位置上元素的加减法计算,结果还是一个矩阵。

假设有两个3x3矩阵 A 和 B,它们的加法计算公式为:

A+B=[a11a12a13a21a22a23a31a32a33]+[b11b12b13b21b22b23b31b32b33]=[a11+b11a12+b12a13+b13a21+b21a22+b22a23+b23a31+b31a32+b32a33+b33]\mathbf{A} + \mathbf{B} = \begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix} + \begin{bmatrix} b_{11} & b_{12} & b_{13} \\ b_{21} & b_{22} & b_{23} \\ b_{31} & b_{32} & b_{33} \end{bmatrix} = \begin{bmatrix} a_{11} + b_{11} & a_{12} + b_{12} & a_{13} + b_{13} \\ a_{21} + b_{21} & a_{22} + b_{22} & a_{23} + b_{23} \\ a_{31} + b_{31} & a_{32} + b_{32} & a_{33} + b_{33} \end{bmatrix}A+B=​a11​a21​a31​​a12​a22​a32​​a13​a23​a33​​​+​b11​b21​b31​​b12​b22​b32​​b13​b23​b33​​​=​a11​+b11​a21​+b21​a31​+b31​​a12​+b12​a22​+b22​a32​+b32​​a13​+b13​a23​+b23​a33​+b33​​​

它们的减法公式为:

A−B=[a11a12a13a21a22a23a31a32a33]+[b11b12b13b21b22b23b31b32b33]=[a11−b11a12−b12a13−b13a21−b21a22−b22a23−b23a31−b31a32−b32a33−b33]\mathbf{A} - \mathbf{B} = \begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix} + \begin{bmatrix} b_{11} & b_{12} & b_{13} \\ b_{21} & b_{22} & b_{23} \\ b_{31} & b_{32} & b_{33} \end{bmatrix} = \begin{bmatrix} a_{11} - b_{11} & a_{12} - b_{12} & a_{13} - b_{13} \\ a_{21} - b_{21} & a_{22} - b_{22} & a_{23} - b_{23} \\ a_{31} - b_{31} & a_{32} - b_{32} & a_{33} - b_{33} \end{bmatrix}A−B=​a11​a21​a31​​a12​a22​a32​​a13​a23​a33​​​+​b11​b21​b31​​b12​b22​b32​​b13​b23​b33​​​=​a11​−b11​a21​−b21​a31​−b31​​a12​−b12​a22​−b22​a32​−b32​​a13​−b13​a23​−b23​a33​−b33​​​

注意:

  • 只有相同维度的矩阵才能进行加减法运算
  • 矩阵加法使用交换律和结合律:A + B = B + A;(A + B) + C = A + (B + C)

GLSL示例:

mat3 A = mat3(
    1.0, 2.0, 3.0,
    4.0, 5.0, 6.0,
    7.0, 8.0, 9.0
);

mat3 B = mat3(
    9.0, 8.0, 7.0,
    6.0, 5.0, 4.0,
    3.0, 2.0, 1.0
);

mat3 C = A + B; // mat(10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0)
mat3 D = A - B; // mat(-8.0, -6.0, -4.0, -2.0, 0.0, 2.0, 4.0, 6.0, 8.0)

矩阵的数乘

矩阵的数乘就是用一个数(标量)去乘m x n矩阵的所有元素,结果还是一个m x n矩阵。

kA=k[a11a12a13a21a22a23a31a32a33]=[ka11ka12ka13ka21ka22ka23ka31ka32ka33]k \mathbf{A} = k \begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix} = \begin{bmatrix} ka_{11} & ka_{12} & ka_{13} \\ ka_{21} & ka_{22} & ka_{23} \\ ka_{31} & ka_{32} & ka_{33} \end{bmatrix}kA=k​a11​a21​a31​​a12​a22​a32​​a13​a23​a33​​​=​ka11​ka21​ka31​​ka12​ka22​ka32​​ka13​ka23​ka33​​​

几何意义:矩阵本身可以看作是一种“空间变换规则”,例如矩阵S,对它数乘一个系数 k=2后:

2S=2[200030001]=[400060002]2 \mathbf{S} = 2 \begin{bmatrix} 2 & 0 & 0 \\ 0 & 3 & 0 \\ 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix} 4 & 0 & 0 \\ 0 & 6 & 0 \\ 0 & 0 & 2 \end{bmatrix}2S=2​200​030​001​​=​400​060​002​​

矩阵 S 是一个缩放矩阵,表示:在x方向缩放 2 倍,在y方向缩放 3 倍,在z方向不变。数乘 2 之后,表示x方向缩放4倍,y方向缩放6倍,z方向缩放2倍。这说明数乘改变了缩放比例,整体放大了原变换的强度。

注:

  • 矩阵数乘满足分配律:(k + v) A = kA + vA; k(A + B) = kA + kB
  • 矩阵数乘满足结合律:(kv)A = k(vA)

ThreeJS示例:

const m = new THREE.Matrix3().set(
  1, 2, 3,
  4, 5, 6,
  7, 8, 9
)

m.multiplyScalar(2)
console.log(m.elements) // [2, 4, 6, 8, 10, 12, 14, 16, 18]

GLSL示例:

const m = new THREE.Matrix3().set(
  1, 2, 3,
  4, 5, 6,
  7, 8, 9
)

m.multiplyScalar(2)
console.log(m.elements) // [2, 4, 6, 8, 10, 12, 14, 16, 18]

矩阵的转置

矩阵转置是将一个矩阵的行列互换的操作,一个mxn的矩阵转置后,得到的结果是一个nxm的矩阵。

(AT)ij=Aji(A^T)_{ij} = A_{ji}(AT)ij​=Aji​ A=[a11a12a13a21a22a23a31a32a33],AT=[a11a21a31a12a22a32a13a23a33]A = \begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix}, \quad A^T = \begin{bmatrix} a_{11} & a_{21} & a_{31} \\ a_{12} & a_{22} & a_{32} \\ a_{13} & a_{23} & a_{33} \end{bmatrix}A=​a11​a21​a31​​a12​a22​a32​​a13​a23​a33​​​,AT=​a11​a12​a13​​a21​a22​a23​​a31​a32​a33​​​

例如:

A=[123456]2×3,AT=[142536]3×3A = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix}_{2 \times 3}, A^T = \begin{bmatrix} 1 & 4 \\ 2 & 5 \\ 3 & 6 \end{bmatrix}_{3 \times 3}A=[14​25​36​]2×3​,AT=​123​456​​3×3​

注:

  • 转置的转置:(AT)T=A(A^T)^T = A(AT)T=A
  • 和的转置:(A+B)T=AT+BT(A+B)^T = A^T + B^T(A+B)T=AT+BT
  • 数乘的转置:(kA)T=kAT(kA)^T = kA^T(kA)T=kAT
  • 乘法的转置(注意顺序反转):(AB)T=BTAT(AB)^T = B^TA^T(AB)T=BTAT

Three.js 示例:

const m = new THREE.Matrix3();
m.set(1, 2, 3, 4, 5, 6, 7, 8, 9)
const n = m.clone().transpose()

console.log(m.elements) // [1, 4, 7, 2, 5, 8, 3, 6, 9]
console.log(n.elements) // [1, 2, 3, 4, 5, 6, 7, 8, 9]

GLSL 示例:

mat3 m = mat3(
  1.0, 2.0, 3.0,
  4.0, 5.0, 6.0,
  7.0, 8.0, 9.0
);

mat3 t = transpose(m);

矩阵的乘法:矩阵乘矩阵

两个矩阵相乘必须满足一个条件:被乘矩阵的列数等于乘数矩阵的行数,如果矩阵A的大小是 m x n,矩阵B的大小是 n x p,那么它们的乘积 C = A x B 就是一个 m x p 大小的矩阵。即:前一个矩阵的列数 = 后一个矩阵的行数,才能相乘。

3 x 3矩阵的计算公式如下:

C=A×B=[a11a12a13a21a22a23a31a32a33]×[b11b12b13b21b22b23b31b32b33]=[a11b11+a12b21+a13b31a11b12+a12b22+a13b32a11b13+a12b23+a13b33a21b11+a22b21+a23b31a21b12+a22b22+a23b32a21b13+a22b23+a23b33a31b11+a32b21+a33b31a31b12+a32b22+a33b32a31b13+a32b23+a33b33]\mathbf{C} = \mathbf{A} \times \mathbf{B} = \begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix} \times \begin{bmatrix} b_{11} & b_{12} & b_{13} \\ b_{21} & b_{22} & b_{23} \\ b_{31} & b_{32} & b_{33} \end{bmatrix} = \begin{bmatrix} a_{11}b_{11}+a_{12}b_{21}+a_{13}b_{31} & a_{11}b_{12}+a_{12}b_{22}+a_{13}b_{32} & a_{11}b_{13}+a_{12}b_{23}+a_{13}b_{33} \\ a_{21}b_{11}+a_{22}b_{21}+a_{23}b_{31} & a_{21}b_{12}+a_{22}b_{22}+a_{23}b_{32} & a_{21}b_{13}+a_{22}b_{23}+a_{23}b_{33} \\ a_{31}b_{11}+a_{32}b_{21}+a_{33}b_{31} & a_{31}b_{12}+a_{32}b_{22}+a_{33}b_{32} & a_{31}b_{13}+a_{32}b_{23}+a_{33}b_{33} \end{bmatrix}C=A×B=​a11​a21​a31​​a12​a22​a32​​a13​a23​a33​​​×​b11​b21​b31​​b12​b22​b32​​b13​b23​b33​​​=​a11​b11​+a12​b21​+a13​b31​a21​b11​+a22​b21​+a23​b31​a31​b11​+a32​b21​+a33​b31​​a11​b12​+a12​b22​+a13​b32​a21​b12​+a22​b22​+a23​b32​a31​b12​+a32​b22​+a33​b32​​a11​b13​+a12​b23​+a13​b33​a21​b13​+a22​b23​+a23​b33​a31​b13​+a32​b23​+a33​b33​​​

即

C=[c11c12c13c21c22c23c31c32c33],cij=∑k=13aikbkjC = \begin{bmatrix} c_{11} & c_{12} & c_{13} \\ c_{21} & c_{22} & c_{23} \\ c_{31} & c_{32} & c_{33} \end{bmatrix}, \quad c_{ij} = \sum_{k=1}^{3} a_{ik} b_{kj}C=​c11​c21​c31​​c12​c22​c32​​c13​c23​c33​​​,cij​=k=1∑3​aik​bkj​

C 也是一个 3x3 矩阵,每个元素的计算公式为:

cij=ai1b1j+ai2b2j+ai3b3j,i,j=1,2,3c_{ij} = a_{i1}b_{1j} + a_{i2}b_{2j} + a_{i3}b_{3j}, \quad i, j = 1, 2, 3cij​=ai1​b1j​+ai2​b2j​+ai3​b3j​,i,j=1,2,3

记忆技巧:结果矩阵的每个元素 Cij 等于 A 的第 i 行与 B 的第 j 列对应元素乘积之和。

一般形式的公式为:

设:

A=[aik]m×p,B=[bkj]p×n,C=AB=[cij]m×nA = [a_{ik}]_{m \times p}, \quad B = [b_{kj}]_{p \times n}, \quad C = AB = [c_{ij}]_{m \times n}A=[aik​]m×p​,B=[bkj​]p×n​,C=AB=[cij​]m×n​

每个元素的公式是:

cij=∑k=1paikbkj,i=1,…,m,  j=1,…,nc_{ij} = \sum_{k=1}^{p} a_{ik} b_{kj}, \quad i=1,\dots,m, \; j=1,\dots,ncij​=k=1∑p​aik​bkj​,i=1,…,m,j=1,…,n

注:

  • 矩阵相乘满足分配律:A(B + C) = AB + AC, (A + B)C = AC + BC
  • 满足结合律:(AB)C = A(BC)
  • 满足标量结合律:k(AB) = (kA)B = A(kB)
  • 不满足交换律,顺序很重要:AB ≠ BA

Three.js 示例:

// A 矩阵
const A = new THREE.Matrix3().set(
  1, 2, 3,
  4, 5, 6,
  7, 8, 9
);

// B 矩阵
const B = new THREE.Matrix3().set(
  9, 8, 7,
  6, 5, 4,
  3, 2, 1
);

// C = A × B
const C = new THREE.Matrix3().copy(A).multiply(B);

console.log(C.elements);
// [1*9+2*6+3*3, 1*8+2*5+3*2, 1*7+2*4+3*1
// 4*9+5*6+6*3, 4*8+5*5+6*2, 4*7+5*4+6*1
// 7*9+8*6+9*3, 7*8+8*5+9*2, 7*7+8*4+9*1]

//[ 30, 24, 18,
//  84, 69, 54, 
// 138, 114, 90]

GLSL 示例:

mat3 A = mat3(
    1.0, 2.0, 3.0,
    4.0, 5.0, 6.0,
    7.0, 8.0, 9.0
);

mat3 B = mat3(
    9.0, 8.0, 7.0,
    6.0, 5.0, 4.0,
    3.0, 2.0, 1.0
);

// 矩阵相乘
mat3 C = A * B;

矩阵的乘法:矩阵和向量相乘

任何一个向量都可以用一维矩阵表示,行向量可以看成一个1xn的矩阵(一行n列),列向量可以看成是一个mx1的矩阵(m行一列)。

根据两个矩阵可以相乘的条件,矩阵和向量相乘有两种形式:

  • 列向量形式:如果 xxx 是列向量 (n×1)(n \times 1)(n×1),常见的乘法是:

    Am×n⋅xn×1=ym×1A_{m \times n} \cdot x_{n \times 1} = y_{m \times 1}Am×n​⋅xn×1​=ym×1​

    结果是一个mx1的列向量,这是最常用的「矩阵乘向量」。

  • 行向量形式:如果 xTx^TxT是行向量 (1×m)(1 \times m)(1×m),那么它可以乘在矩阵的左边:

    x1×mT⋅Am×n=y1×nT x^T_{1 \times m} \cdot A_{m \times n} = y^T_{1 \times n}x1×mT​⋅Am×n​=y1×nT​

    结果是一个1xn的行向量。

计算过程可以参考矩阵相乘的过程,但只需更少的计算,比如:

y=Ax=[a11a12a13a21a22a23a31a32a33]⋅[x1x2x3]=[a11x1+a12x2+a13x3a21x1+a22x2+a23x3a31x1+a32x2+a33x3]y = Ax = \begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix} \cdot \begin{bmatrix} x_{1} \\ x_{2} \\ x_{3} \end{bmatrix} = \begin{bmatrix} a_{11}x_{1} + a_{12}x_{2} + a_{13}x_{3} \\ a_{21}x_{1} + a_{22}x_{2} + a_{23}x_{3} \\ a_{31}x_{1} + a_{32}x_{2}+ a_{33}x_{3} \end{bmatrix}y=Ax=​a11​a21​a31​​a12​a22​a32​​a13​a23​a33​​​⋅​x1​x2​x3​​​=​a11​x1​+a12​x2​+a13​x3​a21​x1​+a22​x2​+a23​x3​a31​x1​+a32​x2​+a33​x3​​​

几何意义:可以把矩阵看成一个线性变换,它把一个向量映射为一个新的向量。如在计算机图形学中,旋转或缩放矩阵作用在向量上得到旋转或缩放后的向量,投影矩阵作用在向量上得到投影坐标。

Three.js 示例:

const m = new THREE.Matrix3().set(
  1, 2, 3,
  4, 5, 6,
  7, 8, 9
)
const v = new THREE.Vector3(1, 2, 3)

// y = m * v
const result = v.clone().applyMatrix3(m)
console.log(result) // {x: 14, y: 32, z: 50}
// {x: 1*1+2*2+3*3, y: 4*1+5*2+6*3, z: 7*1+8*2+9*3}

GLSL 示例:

mat3 m = mat3(
  1.0, 2.0, 3.0,
  4.0, 5.0, 6.0,
  7.0, 8.0, 9.0
);

vec3 v = vec3(1.0, 2.0, 3.0);
vec3 y = m * v;

常用矩阵

  • 方阵(Square Matrix):行数与列数相同,常用于线性变换、特征值、逆矩阵等。

  • 零矩阵(Zero Matrix):所有元素都为 0。

  • 单位矩阵(Identity Matrix):对角线为 1,其余为 0。

    In=[100010001]I_n = \begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}In​=​100​010​001​​
  • 对角矩阵(Diagonal Matrix):也是缩放矩阵,仅主对角线上有元素。运算简单、常用于缩放变换。

    D=[d1000d2000d3]D = \begin{bmatrix} d_1 & 0 & 0 \\ 0 & d_2 & 0 \\ 0 & 0 & d_3 \end{bmatrix}D=​d1​00​0d2​0​00d3​​​

Last updated on

On this page

什么是矩阵矩阵的加减法矩阵的数乘矩阵的转置矩阵的乘法:矩阵乘矩阵矩阵的乘法:矩阵和向量相乘常用矩阵
Back to posts

TrackSiteMapRSS

Last build: 1 minute ago

萌ICP备20254242号

© 2025 Starllow Lab.

Built with ❤️ using Next.js and Fumadocs.