Threejs源码系列- Object3D

Object3D

three.js核心类

js 复制代码
const _v1 = /*@__PURE__*/ new Vector3();
const _q1 = /*@__PURE__*/ new Quaternion();
const _m1 = /*@__PURE__*/ new Matrix4();
const _target = /*@__PURE__*/ new Vector3();

const _position = /*@__PURE__*/ new Vector3();
const _scale = /*@__PURE__*/ new Vector3();
const _quaternion = /*@__PURE__*/ new Quaternion();

const _xAxis = /*@__PURE__*/ new Vector3( 1, 0, 0 );
const _yAxis = /*@__PURE__*/ new Vector3( 0, 1, 0 );
const _zAxis = /*@__PURE__*/ new Vector3( 0, 0, 1 );
  • _v1:V通用向量临时存储,例如在 translateOnAxis 方法中计算平移向量,或在坐标转换时临时存储中间结果。
  • _q1:临时存储旋转四元数,例如在 rotateOnAxis 和 rotateOnWorldAxis 方法中生成旋转四元数,避免每次调用时新建对象。
  • _m1:临时存储变换矩阵,例如在 worldToLocal 方法中计算逆矩阵,或在 lookAt 方法中生成视图矩阵。
  • _target:在 lookAt 方法中存储目标点坐标(世界空间中的注视点),统一处理参数为向量或单独坐标的情况。
  • _position:临时存储位置信息,例如在 lookAt 方法中从世界矩阵提取当前对象的位置。
  • _scale:临时存储缩放信息,主要在矩阵分解(如 applyMatrix4 中从矩阵提取缩放分量)时使用。
  • _quaternion:临时存储旋转信息,例如在矩阵分解或父对象旋转提取时使用(如 lookAt 中处理父对象旋转)。
  • _xAxis_yAxis_zAxis:预定义的 X、Y、Z 轴单位向量((1,0,0)、(0,1,0)、(0,0,1)),在 rotateX/rotateY/rotateZ 等方法中作为旋转轴使用,避免重复创建轴向量。
js 复制代码
class Object3D extends EventDispatcher {
    constructor() {}

    onBeforeShadow() {}
    onAfterShadow() {}
    onBeforeRender() {}
    onAfterRender() {}

    applyMatrix4(matrix) {}
    applyQuaternion(q) {}

    setRotationFromAxisAngle(axis, angle) {}
    setRotationFromEuler(euler) {}
    setRotationFromMatrix(m) {}
    setRotationFromQuaternion(q) {}

    rotateOnAxis(axis, angle) {}
    rotateOnWorldAxis(axis, angle) {}
    rotateX(angle) {}
    rotateY(angle) {}
    rotateZ(angle) {}

    translateOnAxis(axis, distance) {}
    translateX(distance) {}
    translateY(distance) {}
    translateZ(distance) {}

    localToWorld(vector) {}
    worldToLocal(vector) {}

    lookAt(x,y,z) {}

    add(object) {}
    remove(object) {}
    removeFromParent() {}
    clear() {}
    attach(object) {}

    getObjectById(id) {}
    getObjectByName(name) {}
    getObjectByProperty(name, value) {}
    getObjectsByProperty(name, value, result=[]) {}
    getWorldPosition(target) {}
    getWorldQuaternion(target) {}
    getWorldScale(target) {}
    getWorldDirection(target) {}

    raycast() {}

    traverse(callback) {}
    traverseVisible(callback) {}
    traverseAncestors(callback) {}

    updateMatrix() {}
    updateMatrixWorld(force) {}
    updateWorldMatrix(updateParents, updateChildren){}

    toJSON(meta) {}
    clone(recursive) {}
    copy(source, recursive=true) {}

}

updateMatrixWorld 函数、updateWorldMatrix 函数对比

相同点

  • 核心目标一致

    最终都是为了计算对象的世界矩阵(matrixWorld),该矩阵表示对象在全局坐标系中的位置、旋转和缩放的综合变换,计算公式相同:

    • 若对象无父级(parent === null),则 matrixWorld 直接等于本地矩阵(matrix)。
    • 若有父级,则 matrixWorld 是父级世界矩阵与自身本地矩阵的乘积(parent.matrixWorld × matrix)。
  • 依赖本地矩阵更新

    两者都会先检查 matrixAutoUpdate 标志,若为 true,则先调用 updateMatrix() 确保本地矩阵(matrix)是最新的(基于当前 position、rotation、scale 计算)。

  • 支持层级更新

    都能触发子对象(或父对象)的矩阵更新,确保整个层级结构的世界矩阵保持一致。

不同点

维度 updateMatrixWorld(force) updateWorldMatrix(updateParents, updateChildren)
更新方向 从当前对象向下递归更新(子对象)。 可灵活控制:向上更新父对象(updateParents)、向下更新子对象(updateChildren)。
触发条件 仅当 matrixWorldNeedsUpdatetrueforcetrue 时,才更新自身 matrixWorld 无条件计算自身 matrixWorld(只要 matrixWorldAutoUpdatetrue),不受 matrixWorldNeedsUpdate 影响。
参数作用 force:强制更新自身及所有子对象的世界矩阵(忽略 matrixWorldNeedsUpdate)。 updateParents:是否先更新所有父对象的世界矩阵;updateChildren:是否更新所有子对象的世界矩阵。
递归逻辑 自身更新后,强制子对象以 force = true 递归更新(若自身被更新过)。 仅在 updateChildrentrue 时,才递归更新子对象(子对象的 updateParents 固定为 false)。
典型使用场景 自动更新流程(如渲染前触发),依赖 matrixWorldNeedsUpdate 标志优化性能。 手动精确控制更新范围(如获取世界位置前,确保父级矩阵已更新)。

总结

  • updateMatrixWorld自动更新管道的核心 ,依赖状态标志(matrixWorldNeedsUpdate)优化性能,适合渲染循环等自动触发的场景。
  • updateWorldMatrix手动控制工具,允许精确指定更新范围(父级/子级),适合需要手动同步矩阵的场景(如获取世界位置、姿态前)。
相关推荐
凌涘1 天前
从零掌握 CSS 3D:用几行代码让网页"立"起来
three.js
柳杉1 天前
我用Threejs 搓了一个 3D 中国地图设计器,开箱即用
前端·three.js·数据可视化
数据知道7 天前
视觉伪装(下):WebGL 渲染器与厂商特征的底层伪造与屏蔽
javascript·数据采集·webgl·指纹浏览器
niconicoC7 天前
让 Three.js 场景更真实:我用高斯泼溅和 SparkJS 做了一个可交互的 3D Demo
前端·webgl
sinat_384503118 天前
【无标题】
unity·webgl
郝学胜-神的一滴11 天前
[简化版 GAMES 101] 计算机图形学 12:可见性与 Z‑Buffer 深度缓存
unity·godot·图形渲染·three.js·opengl·unreal
VcB之殇12 天前
[Three.js] 实现两个3D模型之间的粒子化切换
前端·javascript·three.js
山河木马13 天前
无框架-原生webGL渲染-底层入门-1
前端·javascript·webgl
郝学胜-神的一滴14 天前
中级OpenGL教程 008:精准控制高光光斑大小与强度
c++·unity·godot·three.js·图形学·opengl·unreal
拾忆丶夜15 天前
unity webgl 阴影条纹问题
unity·游戏引擎·webgl