Skip to content

核心库

目的与范围

核心库提供构成 Three.js 基础的基础类和抽象。它定义与渲染器无关的 3D 场景表示,包括场景图层次结构、几何体数据结构、材质属性和纹理管理。这一层位于数学原始类型和渲染系统之间,使得能够独立于渲染后端创建和操作 3D 内容。

有关这些核心类使用的数学原始类型信息,请参阅数学原始类型。有关这些核心类如何渲染到屏幕的细节,请参阅渲染架构

架构概览

核心库由四个主要子系统组成,它们协同工作来表示 3D 场景:

核心库架构

SVG
100%

Object3D:场景图基础

Object3D 是 Three.js 中所有可渲染和不可渲染对象的基类。它提供层次变换、事件分发和场景图遍历的公共接口。

Object3D 核心属性与关系

SVG
100%

变换系统

Object3D 同时维护欧拉角和四元数表示的变换,两者间自动同步。变换层次结构通过局部和世界矩阵管理:

属性类型用途
positionVector3相对于父级的局部位置
rotationEuler作为欧拉角的局部旋转(与四元数同步)
quaternionQuaternion作为四元数的局部旋转(与旋转同步)
scaleVector3局部缩放
matrixMatrix4局部变换矩阵
matrixWorldMatrix4世界变换矩阵
matrixAutoUpdateboolean从位置/旋转/缩放自动计算局部矩阵
matrixWorldAutoUpdateboolean从层次结构自动计算世界矩阵
pivotVector3旋转和缩放变换的枢轴点

变换矩阵通过 updateMatrix()updateMatrixWorld() 计算。当 matrixAutoUpdate 为 true 时,每帧从位置、旋转和缩放出局部矩阵。当 matrixWorldAutoUpdate 为 true 时,通过将父级的世界矩阵与局部矩阵相乘来计算世界矩阵。

层次管理

场景图使用父子关系构建。层次操作的关键方法:

方法参数用途
add(object)Object3D添加子对象,触发 'added' 和 'childadded' 事件
remove(object)Object3D移除子对象,触发 'removed' 和 'childremoved' 事件
removeFromParent()-从此对象的父级中移除
clear()-移除所有子对象
attach(object)Object3D添加子对象同时保持其世界变换
traverse(callback)Function在此对象和所有后代上执行回调
traverseVisible(callback)Function仅在可见对象上执行回调
traverseAncestors(callback)Function在所有祖先上执行回调

EventDispatcher 集成

Object3D 扩展 EventDispatcher,提供发布-订阅事件系统。内置事件包括:

  • added:当对象添加到父级时触发
  • removed:当对象从父级移除时触发
  • childadded:当添加子对象时触发(包含 child 属性)
  • childremoved:当移除子对象时触发(包含 child 属性)

BufferGeometry:顶点数据存储

BufferGeometry 使用存储在 BufferAttribute 实例中的类型化数组表示 mesh、线或点几何体。它提供高效的数据传输到 GPU,并支持索引和非索引几何体。

BufferGeometry 数据流

SVG
100%

属性管理

几何体属性存储在以属性名为键的字典(attributes)中。常见属性包括:

属性项目大小类型用途
position3Float32顶点位置(x, y, z)
normal3Float32顶点法线
uv2Float32纹理坐标
uv12Float32第二组纹理坐标
color3 或 4Float32顶点颜色(RGB 或 RGBA)
tangent4Float32切线向量(w 分量包含手性)
skinIndex4Uint16蒙皮网格的骨骼索引
skinWeight4Float32蒙皮网格的骨骼权重

属性操作的关键方法:

// 来自 BufferGeometry 类
setAttribute(name, attribute)    // 设置属性
getAttribute(name)               // 检索属性
deleteAttribute(name)            // 移除属性
hasAttribute(name)               // 检查属性是否存在

索引与非索引几何体

几何体可以是索引的(三角形间共享顶点)或非索引的(每个三角形有唯一顶点):

  • 索引几何体:使用 index 属性(Uint16 或 Uint32)引用顶点。每三个连续索引定义一个三角形。
  • 非索引几何体:当 index 为 null 时,每三个连续顶点定义一个三角形。

toNonIndexed() 方法通过将共享顶点复制来将索引几何体转换为非索引格式。

绘制组

组允许使用不同材质渲染几何体的不同部分。每个组指定:

属性类型用途
startnumber第一个顶点(非索引)或第一个索引(索引)
countnumber要渲染的顶点或索引数量
materialIndexnumber材质数组中的索引

边界体积计算

BufferGeometry 计算轴对齐边界框(Box3)和边界球(Sphere)用于视锥剔除和相交测试:

  • computeBoundingBox():从位置属性和形态目标计算 boundingBox
  • computeBoundingSphere():使用比边界框更紧密的算法计算 boundingSphere

当定义 morphAttributes.position 时,两种方法都考虑形态目标位置。

法线和切线生成

几何体提供从位置数据计算顶点法线和切线的方法:

  • computeVertexNormals():计算面法线并为共享顶点平均化(索引)或直接分配面法线(非索引)
  • computeTangents():计算用于法线映射的切线向量(需要位置、法线、uv 和索引属性)

BufferAttribute:类型化数组管理

BufferAttribute 包装类型化数组并提供元数据以实现高效的 GPU 传输。它提供访问和操作顶点数据的方法。

BufferAttribute 结构

SVG
100%

数据访问方法

BufferAttribute 为常见项目大小提供类型化访问器:

方法参数用途
getX(index)index获取第一个分量
getY(index)index获取第二个分量
getZ(index)index获取第三个分量
getW(index)index获取第四个分量
setX(index, x)index, x设置第一个分量
setY(index, y)index, y设置第二个分量
setZ(index, z)index, z设置第三个分量
setW(index, w)index, w设置第四个分量
setXY(index, x, y)index, x, y设置两个分量
setXYZ(index, x, y, z)index, x, y, z设置三个分量
setXYZW(index, x, y, z, w)index, x, y, z, w设置四个分量

交错属性

InterleavedBufferInterleavedBufferAttribute 支持将多个属性打包到单个类型化数组中,减少内存开销并提高缓存一致性:

SVG
100%

每个 InterleavedBufferAttribute 引用具有 offsetitemSize 的共享缓冲区,允许高效的数据布局:[x,y,z,nx,ny,nz,u,v, x,y,z,nx,ny,nz,u,v, ...]

实例化属性

InstancedBufferAttribute 扩展 BufferAttribute 用于实例化渲染,其中每个实例可以有唯一的属性值:

  • meshPerAttribute:定义每个属性值使用多少实例(通常为 1)
  • InstancedBufferGeometry 一起使用,用于渲染具有变化属性的几何体多个副本

InstancedInterleavedBuffer 为交错数据提供相同功能。

材质:表面外观

Material 是所有材质的抽象基类,定义控制表面在渲染时外观的属性。它为混合、深度测试、模板操作和自定义着色器钩子提供公共接口。

材质属性类别

SVG
100%

材质属性组

混合与透明度

属性类型默认值用途
blendingConstantNormalBlending混合模式(Normal, Additive, Subtractive, Multiply, Custom, None)
transparentbooleanfalse材质是否透明(影响渲染顺序)
opacitynumber1.0材质不透明度(0.0 = 完全透明, 1.0 = 不透明)
blendSrcConstantSrcAlphaFactor源混合因子(需要 CustomBlending)
blendDstConstantOneMinusSrcAlphaFactor目标混合因子(需要 CustomBlending)
blendEquationConstantAddEquation混合方程(Add, Subtract, ReverseSubtract, Min, Max)

深度与模板

属性类型默认值用途
depthTestbooleantrue启用深度测试
depthWritebooleantrue写入深度缓冲区
depthFuncConstantLessEqualDepth深度比较函数
stencilWritebooleanfalse启用模板操作
stencilFuncConstantAlwaysStencilFunc模板比较函数
stencilRefnumber0模板测试的参考值

材质回调

材质提供在渲染期间自定义的钩子:

回调参数用途
onBeforeRenderrenderer, scene, camera, geometry, object, group在渲染对象前调用
onBeforeCompileshaderobject, renderer编译前修改着色器源代码(仅 WebGLRenderer)
customProgramCacheKey-返回字符串键用于着色器缓存标识

onBeforeCompile 回调为 WebGLRenderer 启用着色器修改:

material.onBeforeCompile = function(shader, renderer) {
    // 修改 shader.vertexShader 或 shader.fragmentShader
    // 访问 shader.uniforms
}

纹理:图像数据管理

Texture 封装图像数据和材质的采样参数。它使用 Source 对象在多个纹理间共享图像数据。

纹理结构与关系

SVG
100%

纹理坐标变换

纹理通过偏移、重复、中心和旋转支持 UV 变换:

  • offset:UV 空间中的平移
  • repeat:UV 空间中的缩放(值 > 1 平铺纹理)
  • center:UV 空间中的旋转中心
  • rotation:弧度单位的旋转角度

matrixAutoUpdate 为 true 时,这些属性用于通过 updateMatrix() 计算 matrix,应用变换:matrix.setUvTransform(offset.x, offset.y, repeat.x, repeat.y, rotation, center.x, center.y)

纹理源共享

Source 类 (src/textures/Source.js) 保存实际图像数据,可在多个 Texture 实例间共享。这对以下情况很有用:

  • 从同一图像创建具有不同采样参数的多个纹理
  • 实现纹理图集,其中多个纹理引用相同源但具有不同的 UV 变换

序列化与加载

核心库包含用于从 JSON 格式反序列化 Three.js 对象的加载器,支持具有几何体、材质、纹理、动画和骨骼层次结构的完整场景图。

ObjectLoader 数据流

SVG
100%

ObjectLoader 流水线

ObjectLoader 分阶段解析 JSON 序列化场景:

  1. 形状 (src/loaders/ObjectLoader.js270-288):解析挤出几何体的 2D 形状
  2. 几何体 (src/loaders/ObjectLoader.js321-368):使用 BufferGeometryLoader 或程序化几何体类解析几何数据
  3. 图像 (src/loaders/ObjectLoader.js423-633):通过 ImageLoader 加载图像或反序列化内嵌数据纹理
  4. 纹理 (src/loaders/ObjectLoader.js635-740):使用采样参数创建 Texture 实例
  5. 材质 (src/loaders/ObjectLoader.js371-399):使用 MaterialLoader 解析材质
  6. 对象 (src/loaders/ObjectLoader.js743-1045):递归构建 Object3D 层次结构
  7. 骨骼 (src/loaders/ObjectLoader.js290-318):解析蒙皮网格的骨骼数据
  8. 绑定 (src/loaders/ObjectLoader.js1047-1108):将骨骼附加到网格并解析光源目标

MaterialLoader

MaterialLoader 从 JSON 反序列化材质属性,创建具体材质类的实例:

// createMaterialFromType() 识别的材质类型
MeshBasicMaterial, MeshLambertMaterial, MeshPhongMaterial, 
MeshStandardMaterial, MeshPhysicalMaterial, MeshToonMaterial,
MeshNormalMaterial, MeshMatcapMaterial, MeshDepthMaterial,
MeshDistanceMaterial, LineBasicMaterial, LineDashedMaterial,
PointsMaterial, SpriteMaterial, ShaderMaterial, RawShaderMaterial,
ShadowMaterial

加载器设置材质属性并从纹理字典解析纹理引用。

序列化格式

Object3D.toJSON()Material.toJSON() 将对象序列化为与 ObjectLoader 兼容的 JSON 格式:

元数据内容
metadata.version4.7
metadata.type'Object' 或 'Material'
metadata.generator'Object3D.toJSON' 或 'Material.toJSON'

序列化捕获:

  • 对象层次结构和变换
  • 几何体与材质引用(通过 UUID)
  • userData 中的自定义属性
  • 动画剪辑
  • SkinnedMesh 的骨骼绑定

WebGL 资源管理

虽然核心库与渲染器无关,但它通过专门的资源管理系统与 WebGL 接口:

WebGL 资源管理流

SVG
100%

WebGLGeometries

WebGLGeometries 管理几何体资源的生命周期:

  • 通过几何体 ID 使用 WeakMap 跟踪几何体
  • 通过 EventDispatcher 'dispose' 事件注册处置处理器
  • 通过 WebGLAttributes 更新属性缓冲区
  • 为线框渲染模式生成线框索引
  • 管理 InstancedBufferGeometry 实例计数

WebGLAttributes

WebGLAttributes 管理 BufferAttribute 数据的 WebGL 缓冲区对象:

  • 使用 gl.createBuffer() 创建 VBO 并通过 gl.bufferData() 上传数据
  • 使用 updateRanges 通过 gl.bufferSubData() 增量更新缓冲区
  • 合并相邻更新范围以最小化 GPU 命令开销
  • 将 TypedArray 类型映射到 WebGL 常量(FLOAT, HALF_FLOAT, UNSIGNED_SHORT 等)

WebGLBindingStates

WebGLBindingStates 管理顶点数组对象(VAO)以缓存属性绑定:

  • 为每个(对象, 几何体, 程序, 材质)组合创建唯一 VAO
  • 缓存顶点属性指针配置
  • 通过绑定缓存的 VAO 减少状态更改
  • 处理 InstancedMesh 的实例化属性
  • 跟踪线框与实体几何体变体

WebGLObjects

WebGLObjects 协调每帧的几何体和属性更新:

  • 使用帧跟踪每帧更新一次几何体
  • 更新 InstancedMesh 的实例矩阵
  • 触发 SkinnedMesh 的骨骼更新
  • 管理实例化网格资源的处置

WebGLProperties

WebGLProperties 使用 WeakMap 提供通用属性存储,允许渲染器特定的元数据附加到核心对象而无需修改其类定义。

与其他系统的关系

核心库作为其他 Three.js 系统的基础:

系统关系
数学原始类型(#2.1)核心库使用 Vector3, Matrix4, Quaternion 等进行变换
常量(#2.2)核心库引用混合模式、纹理格式等的常量
渲染(#3)渲染器消费核心库对象以生成 GPU 命令
资源管线(#4)加载器从外部文件格式创建核心库对象
交互系统(#5)射线检测和动画系统在核心库场景图上操作