Threejs源码系列- Matrix4

36 阅读8分钟

Matrix4 类

class Matrix4 {
    constructor( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {}

    set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {}

    identity() {}

    clone() {}

    copy( m ) {}

    copyPosition( m ) {}

    setFromMatrix3( m ) {}

    extractBasis( xAxis, yAxis, zAxis ) {}

    makeBasis( xAxis, yAxis, zAxis ) {}

    extractRotation( m ) {}

    makeRotationFromEuler( euler ) {}

    makeRotationFromQuaternion( q ) {}

    lookAt( eye, target, up ) {}

    multiply( m ) {}

    premultiply( m ) {}

    multiplyMatrices( a, b ) {}

    multiplyScalar( s ) {}

    determinant() {}

    transpose() {}

    setPosition( x, y, z ) {}

    invert() {}

    scale( v ) {}

    getMaxScaleOnAxis() {}

    makeTranslation( x, y, z ) {}

    makeRotationX( theta ) {}

    makeRotationY( theta ) {}

    makeRotationZ( theta ) {}

    makeRotationAxis( axis, angle ) {} 

    makeScale( x, y, z ) {}

    makeShear( xy, xz, yx, yz, zx, zy ) {}

    compose( position, quaternion, scale ) {}

    decompose( position, quaternion, scale ) {}

    makePerspective( left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false ) {}

    makeOrthographic( left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false ) {}

    equals( matrix ) {}

    fromArray( array, offset = 0 ) {}

    toArray( array = [], offset = 0 ) {}


}

extractBasis 函数

用途
  • 提取模型矩阵的局部坐标系轴方向(例如获取物体的右、上、前方向)。
  • 分解矩阵的旋转和缩放分量(基向量的长度即缩放比例,方向即旋转结果)。
  • 在骨骼动画或坐标系转换中,用于获取子节点相对于父节点的朝向。

makeBasis 函数

用途
  • 在 3D 图形中创建自定义局部坐标系(如骨骼动画中的骨骼坐标系、相机的观察坐标系)。
  • 基于已知的三个轴向量快速构建变换矩阵,用于物体的姿态控制或坐标转换。

extractRotation 函数

用于从给定的 4x4 矩阵中提取旋转分量,并将当前矩阵设置为仅包含该旋转信息的矩阵(去除缩放和平移)。

用途
  • 从包含缩放、旋转、平移的复合变换矩阵中分离出旋转部分。
  • 用于动画、物理模拟等需要单独处理旋转信息的场景。

makeRotationFromEuler 函数

用于根据欧拉角(Euler angles)创建对应的 4x4 旋转矩阵。

用途
  • 将欧拉角转换为矩阵形式,用于 3D 物体的旋转变换(如模型姿态调整、相机视角旋转)。
  • 作为欧拉角与其他旋转表示(如四元数)之间转换的中间步骤。

lookAt 函数

用于构建一个表示 “观察方向” 的旋转矩阵(常用于相机或物体朝向目标的变换)。其核心功能是根据观察点(eye)、目标点(target)和上方向向量(up),计算出对应的旋转矩阵,使物体或相机朝向目标方向。

用途
  • 相机视角控制:让相机始终朝向目标点(如第三人称视角跟踪物体)。
  • 物体朝向设置:使物体正面朝向目标点(如 NPC 看向玩家)。
  • 视图矩阵构建:作为 3D 渲染中视图变换的核心,将世界坐标系转换为相机坐标系。
示例
const camera = new THREE.Camera();
const eye = new THREE.Vector3(0, 0, 10); // 相机位置
const target = new THREE.Vector3(0, 0, 0); // 目标点
const up = new THREE.Vector3(0, 1, 0); // 上方向(Y轴)

camera.matrix.lookAt(eye, target, up); // 构建看向目标的旋转矩阵
camera.matrixAutoUpdate = false; // 禁用自动更新,使用自定义矩阵

multiplyMatrices 函数

实现两个 4x4 矩阵 a(左矩阵)和 b(右矩阵)的乘法,结果为 this = a × b(遵循矩阵乘法的 “行 × 列” 规则)。

矩阵乘法是 3D 图形学中变换组合的核心操作(如将旋转、缩放、平移等变换合并为一个复合变换)。

用途
  • 组合多个变换(旋转、缩放、平移等)为单个矩阵,减少顶点变换时的计算量。
  • 在 3D 渲染管线中构建模型视图投影矩阵(MVP 矩阵)等复合变换。

multiplyScalar 函数

对矩阵的 16 个元素(4x4 矩阵共 16 个元素)分别执行与标量 s 的乘法操作,实现矩阵的缩放变换。

用途
  • 整体缩放矩阵所代表的变换效果(需注意可能破坏旋转矩阵的正交性)。
  • 调整矩阵的比例系数,例如在物理模拟或坐标空间转换中统一缩放变换。
示例
const matrix = new THREE.Matrix4().makeTranslation(1, 2, 3); // 平移矩阵
matrix.multiplyScalar(2); // 所有元素乘以2
// 结果矩阵的平移分量变为 (2, 4, 6),其他元素也按比例缩放

determinant 函数

计算当前 4x4 矩阵的行列式值,采用解析法直接根据矩阵元素按公式展开计算。

在 3D 图形学中常用于判断矩阵是否可逆(行列式不为 0 则可逆)、计算矩阵的逆矩阵等场景。

用途
  • 矩阵求逆(invert 方法中需先计算行列式,若为 0 则无法求逆)。
  • 判断矩阵是否为可逆矩阵(行列式非 0 则可逆)。
  • 计算矩阵对空间的缩放比例或定向变化。

transpose 函数

用于对当前 4x4 矩阵进行转置操作(将矩阵的行与列互换),并返回当前矩阵的引用。

用途
  • 计算正交矩阵(如旋转矩阵)的逆矩阵(直接转置即可,无需复杂计算)。
  • 转换法向量的变换矩阵(修正非均匀缩放对法向量的影响)。
  • 矩阵运算中调整行列顺序以满足特定计算需求(如矩阵乘法的交换律补偿)。

示例

  • 若原矩阵为单位矩阵,转置后仍为单位矩阵;若原矩阵是一个平移矩阵,转置后平移分量会从第 3 列(te[12]、te[13]、te[14])移至第 3 行(te[3]、te[7]、te[11])。

getMaxScaleOnAxis 函数

用于计算当前 4x4 矩阵在 X、Y、Z 三个轴上的最大缩放比例。

用途
  • 常用于判断模型的缩放程度,例如在碰撞检测、LOD(细节层次)切换等场景中,当模型缩放超过一定阈值时执行相应逻辑(如调整碰撞体大小、切换模型精度)。
示例

若矩阵是一个缩放矩阵 makeScale(2, 3, 1),则:

  • scaleXSq = 2² + 0 + 0 = 4
  • scaleYSq = 0 + 3² + 0 = 9
  • scaleZSq = 0 + 0 + 1² = 1
  • 最大缩放比例为 √9 = 3(Y 轴)。

makeTranslation 函数

用于将当前 4x4 矩阵设置为一个平移变换矩阵,并返回当前矩阵的引用。

用途
  • 用于设置物体的初始位置或动态修改位置(如动画中物体的位移)。
  • 作为相机变换的一部分,调整相机在场景中的观察位置。
  • 在坐标空间转换中(如模型空间到世界空间),用于添加物体的位置偏移。
示例
  • 若调用 matrix.makeTranslation(5, 10, 15),矩阵将被设置为:

    [1, 0, 0, 5]
    [0, 1, 0, 10]
    [0, 0, 1, 15]
    [0, 0, 0, 1]
    
  • 若调用 matrix.makeTranslation(new Vector3(2, 4, 6)),效果与上述相同,矩阵第 4 列将被设置为 (2, 4, 6)。

makeRotationAxis 函数

用于将当前 4x4 矩阵设置为一个绕任意轴旋转的变换矩阵。

用途
  • 实现复杂的旋转动画(如物体绕自身对角线、任意方向的轴旋转)。
  • 相机控制(如第一人称视角中绕视线方向的旋转)。
  • 物理引擎中的刚体旋转模拟,支持任意轴的扭矩作用。

makeShear 函数

用于将当前 4x4 矩阵设置为一个剪切变换矩阵。

用途
  • 用于物体的非线性变形(如倾斜、扭曲效果)。
  • 在动画中模拟弹性形变或透视扭曲。
  • 作为复杂变换的组成部分,与旋转、缩放等组合使用,实现更丰富的视觉效果。

makeShear 方法通过构造剪切矩阵,实现了三维空间中各坐标轴之间的交叉变形控制,是 Three.js 中实现灵活几何变换的重要工具。

compose 函数

用于将位置(position)、旋转(quaternion)、缩放(scale) 三个变换分量组合成一个 4x4 变换矩阵。

用途
  • 在三维引擎中,将物体的局部变换(位置、旋转、缩放)合并为一个矩阵,用于高效计算顶点的最终位置(通过矩阵与顶点的乘法)。
  • 作为 decompose 方法的逆操作(decompose 是将矩阵拆分为位置、旋转、缩放,compose 是将三者合并为矩阵)。

discompose 函数

用于将一个 4x4 变换矩阵拆解为位置(position)、旋转(quaternion)、缩放(scale) 三个独立的变换分量。它是 compose 方法的逆操作,在三维图形学中用于从合并的变换矩阵中提取原始变换信息。

用途
  • 在三维引擎中,从物体的世界矩阵中提取局部变换(如编辑器中显示物体的位置、旋转、缩放参数)。
  • 用于动画系统中,将矩阵形式的变换转换为可插值的分量(位置、旋转、缩放)。

makePerspective 函数

用于创建一个透视投影矩阵。在三维图形学中,透视投影矩阵的作用是将三维空间中的点映射到二维屏幕上,同时模拟人眼的透视效果(近大远小),是相机投影变换的核心实现。

用途
  • PerspectiveCamera(透视相机)的核心方法,相机的 updateProjectionMatrix 会调用此方法生成投影矩阵。
  • 决定三维场景如何被 “拍摄” 到二维屏幕,直接影响渲染结果的透视效果和视野范围。

makeOrthographic 函数

用于创建一个正交投影矩阵。在三维图形学中,正交投影矩阵的作用是将三维空间中的点映射到二维屏幕上,且物体的大小不会因距离相机的远近而变化(无透视效果),适用于 2D 渲染、工程制图等场景。

用途
  • OrthographicCamera(正交相机)的核心方法,相机的 updateProjectionMatrix 会调用此方法生成投影矩阵。
  • 用于不需要透视效果的场景,如 2D 游戏、建筑蓝图渲染、UI 界面等。