WebGL从零开始(六)—— 复习数学知识

8/21/2026 WebGL

# 1.向量

既有大小(Length/Magnitude)又有方向(Direction)的量。在 WebGL 中常用来表示空间中的点、方向、颜色、法线等。

# 1.1向量的运算

  • 点乘 (Dot Product):dot(a, b)。结果是标量。几何意义: ∣a∣∣b∣cos(θ)。常用于计算夹角、判断朝向(同向为正,垂直为0,反向为负),是 漫反射光照 的核心。
  • 叉乘 (Cross Product):cross(a, b)。结果是向量,且垂直于 a 和 b 构成的平面。遵循右手定则。常用于计算法线、判断点在直线的哪一侧。 -归一化 (Normalize):normalize(v),保持方向不变,将长度变为 1(单位向量)。光照计算必备。

示例:

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
  vec2 uv = fragCoord / iResolution.xy;

  // 1. 点乘:计算两个向量的相似度(常用于光照)
  vec3 lightDir = normalize(vec3(1.0, 1.0, 0.0));
  vec3 normal = vec3(0.0, 1.0, 0.0); // 朝上的法线
  float diff = max(dot(lightDir, normal), 0.0); // 结果在 0~1 之间

  // 2. 叉乘:计算垂直于两个向量的新向量(常用于求法线)
  vec3 tangent = vec3(1.0, 0.0, 0.0);
  vec3 bitangent = cross(normal, tangent); // 得到垂直于两者的向量
}
1
2
3
4
5
6
7
8
9
10
11
12

# 2.矩阵

3D 变换的载体。WebGL 使用 4x4 矩阵(齐次坐标),第四维 w 用于处理平移和透视除法。 GLSL ES中,支持 2、3、4维的矩阵:mat2, mat3, mat4。

# 1.矩阵的运算

  • 矩阵加法:
  • 矩阵减法:
  • 矩阵乘法:C = A * B。不满足交换律
  • 矩阵除法:
  • 列主序 (Column-Major):OpenGL/WebGL 在内存中按列存储矩阵。
  • MVP 变换链:gl_Position = Projection * View * Model * vec4(position, 1.0); (从右向左读:先模型,再视图,最后投影)。

下面是一个顶点着色器

attribute vec4 a_Position;
uniform mat4 u_ModelMatrix;      // 本地 -> 世界
uniform mat4 u_ViewMatrix;       // 世界 -> 相机
uniform mat4 u_ProjectionMatrix; // 相机 -> 裁剪空间

void main() {
    // 注意:矩阵乘法是从右向左读的!
    gl_Position = u_ProjectionMatrix * u_ViewMatrix * u_ModelMatrix * a_Position;
}
1
2
3
4
5
6
7
8
9

# 3.逆矩阵

矩阵的逆(inverse of a matrix)是数学中满足特定条件的方阵,其与原矩阵相乘得到单位矩阵,类似于数的倒数关系,记作A⁻¹。

可逆矩阵一定是方阵,且其逆矩阵是唯一的。

对于一个n阶方阵A,如果存在一个n阶方阵B,使得AB=BA=I(I为单位矩阵),则称A是可逆的,并把B称为A的逆矩阵,记作A⁻¹。

# 矩阵的逆的解法:

# 1.伴随矩阵法

适用于 二阶或三阶矩阵 对于一个 n×n 的可逆矩阵 A ,其逆矩阵公式为:A⁻¹=$\frac{1}{∣A∣}$⋅A∗

其中 A∗ 就是 A 矩阵的 伴随矩阵。 ∣A∣ 是矩阵 A 的行列式(必须 ≠0 ,否则无逆矩阵)

A* 是代数余子式矩阵的转置。

A*ij 的计算 Aij=(−1)i+j⋅Mij

其中 M**ij 是划去第 i 行和第 j 列后剩下的行列式。

# 2.矩阵的行列式

一个n×n的方阵A的行列式记为det(A)或者|A|,一个2×2矩阵的行列式可表示如下:

img

行列式的计算法:从左到右对角线乘积之和+从右到左对角线乘积之和的负数:

如三阶矩阵(a,b,c,d,e,f,g,h,i) 的行列式:

# 初等行变换法

也称高斯-若尔当消元法。这是处理 3×3 或更大矩阵时最常用的方法,也适合计算机编程实现。

原理:构造一个增广矩阵 (A∣I) ,其中 I 是单位矩阵。 通过初等行变换,将左边的 A 变为单位矩阵 I 。此时,右边的 I 就会自动变为 A−1 。 即: (A∣I) 行变换 (I∣A−1)

如:矩阵B $$ \begin{pmatrix} 1 & 2 & 3 \ 2 & 5 & 3 \ 1 & 0 & 8 \end{pmatrix} $$

步骤 1:构造增广矩阵 (B∣I)

$$ \left( \begin{array}{ccc|ccc} 1 & 2 & 3 & 1 & 0 & 0 \ 2 & 5 & 3 & 0 & 1 & 0 \ 1 & 0 & 8 & 0 & 0 & 1 \end{array} \right) $$

步骤 2:进行行变换,目标是将左边变为单位矩阵

  1. 消去第一列下方的数:

    • R2−2R1 (第2行减去第1行的2倍)
    • R3−R1 (第3行减去第1行)

$$\left( \begin{array}{ccc|ccc} 1 & 2 & 3 & 1 & 0 & 0 \ 0 & 1 & -3 & -2 & 1 & 0 \ 0 & -2 & 5 & -1 & 0 & 1 \end{array} \right)$$

  1. 消去第二列下方的数:
  • R3+2R2 (第3行加上第2行的2倍)

$$\left(\begin{array}{ccc|ccc} 1 & 2 & 3 & 1 & 0 & 0 \ 0 & 1 & -3 & -2 & 1 & 0 \ 0 & 0 & -1 & -5 & 2 & 1 \end{array}\right)$$

  1. 将主对角线元素变为 1:

    • R3×(−1) (第3行乘以 -1)

$$\left(\begin{array}{ccc|ccc} 1 & 2 & 3 & 1 & 0 & 0 \ 0 & 1 & -3 & -2 & 1 & 0 \ 0 & 0 & 1 & 5 & -2 & -1 \end{array}\right)$$

 现在左边已经是上三角矩阵,接下来从下往上消元

​

  1. 消去第三列上方的数:

    • R2+3R3 (第2行加上第3行的3倍)

      右边计算: (−2)+15=13 , 1+(−6)=−5 , 0+(−3)=−3

    • R1−3R3 (第1行减去第3行的3倍)

      右边计算:1−15=−14 , 0−(−6)=6 , 0−(−3)=3

$$\left(\begin{array}{ccc|ccc} 1 & 2 & 0 & -14 & 6 & 3 \ 0 & 1 & 0 & 13 & -5 & -3 \ 0 & 0 & 1 & 5 & -2 & -1 \end{array}\right)$$

  1. 消去第二列上方的数:

    • R1−2R2 (第1行减去第2行的2倍)

    右边计算: −14−26=−40 , 6−(−10)=16 , 3−(−6)=9

$$\left(\begin{array}{ccc|ccc} 1 & 0 & 0 & -40 & 16 & 9 \ 0 & 1 & 0 & 13 & -5 & -3 \ 0 & 0 & 1 & 5 & -2 & -1 \end{array}\right)$$

  1. 得出结果

    左边已变为单位矩阵,右边即为逆矩阵:

$$\left(\begin{array}{ccc} -40 & 16 & 9 \ 13 & -5 & -3 \ 5 & -2 & -1 \end{array}\right)$$

# 3.极坐标

O点的射线Ox做极轴,一般以逆时针为正方向。在 Shader 中画圆、扇形、波浪,或实现物体的圆周运动。 公式转换: x=r⋅cos(θ) , y=r⋅sin(θ) 。

示例:会呼吸的圆

uniform float u_Time;
attribute vec2 a_TexCoord; // 假设传入 0.0~1.0 的纹理坐标

void main() {
    vec2 uv = a_TexCoord;
    vec2 center = vec2(0.5);
    
    // 计算当前点到中心的距离
    float dist = distance(uv, center);
    
    // 使用 sin 函数让半径随时间变化(呼吸效果)
    float radius = 0.2 + 0.05 * sin(u_Time * 3.0);
    
    // step(a,b): b < a 返回 1.0, 否则返回 0.0
    float circle = step(dist, radius); 
    gl_FragColor = vec4(vec3(circle), 1.0);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 4.坐标系转换

理解 3D 渲染管线必须掌握的五大空间:

  1. 本地空间 (Local Space):模型自身的坐标系。
  2. 世界空间 (World Space):所有模型共存的绝对坐标系(通过 Model Matrix(模型矩阵) 变换)。
  3. 观察/相机空间 (View Space):以相机为原点的坐标系(通过 View Matrix(视图矩阵) 变换)。
  4. 裁剪空间 (Clip Space):经过投影矩阵变换后的空间,超出 [−1,1] 范围的会被裁剪(通过 Projection Matrix(投影矩阵) 变换)。
  5. 屏幕空间 (Screen Space):最终映射到 2D 像素的坐标。

# 5.欧拉

用三个角度(Pitch 俯仰, Yaw 偏航, Roll 翻滚)来描述 3D 旋转。

了解 致命缺陷:万向节死锁 (Gimbal Lock)。当两个旋转轴重合时,会丢失一个维度的旋转自由度。在底层引擎和复杂动画中,尽量避免直接使用欧拉角进行插值或连续旋转。

# 6.四元数

用 4 个分量 (x,y,z,w) 表示 3D 旋转的数学工具。

  • 优势:完美解决万向节死锁;支持平滑的球面线性插值(Slerp),非常适合相机平滑跟随和骨骼动画。
  • 劣势:不直观,人类难以直接手写四元数,通常在 JS 端用库(如 gl-matrix)计算好后传给 Shader。

# 7.齐次坐标

齐次坐标是用 n+1 维向量表示 n 维空间中点的坐标系统‌,如二维的笛卡尔坐标(x,y),它的齐次坐标为(x,y,w),w默认是1,那么会有

  (x,y) = (x,y,1) = (x,y,2) ...
1

(x,y,1)、(x,y,2)都是(x,y) w只要是大于0的数,那么都(x,y,w)都代表(x,y)。w等于0,代表的就是无穷远。

Last Updated: 9/22/2026, 9:27:15 AM