Skip to content

渲染架构概览

目的与范围

本文档提供 Three.js 渲染子系统的架构概览,涵盖场景如何从场景图表示转换为屏幕上的像素。渲染架构包含 WebGL 和 WebGPU 后端、着色器程序管理、状态缓存和资源协调。

有关特定子系统的详细信息:

有关场景图结构和对象层次:见场景图与 Object3D

渲染器架构概览

Three.js 提供两个主要渲染后端,实现为独立类。WebGLRenderer 类(自 r163 起使用,仅 WebGL 2)作为主要生产渲染器,而 WebGPU 渲染器代表下一代图形 API 支持。

高层渲染器结构

SVG
100%

渲染子系统组织

WebGLRenderer 将专门任务委托给模块化子系统,每个子系统管理渲染管线的特定方面。

子系统主要类职责
着色器管理WebGLPrograms程序选择、编译、缓存
状态缓存WebGLStateGL 状态变更跟踪、去重
几何体上传WebGLGeometriesVBO 创建、属性绑定
纹理管理WebGLTextures纹理上传、参数缓存
渲染协调WebGLRenderLists对象排序(不透明/透明)
光照设置WebGLRenderStates每场景光照累积
阴影渲染WebGLShadowMap阴影图生成、过滤
能力检测WebGLCapabilitiesGPU 限制、扩展可用性
资源跟踪WebGLInfo绘制调用计数、内存统计

帧渲染流

渲染过程遵循从场景遍历到最终像素输出的明确定义序列。WebGLRenderer.render() 方法编排这个多阶段管线。

渲染方法执行流

SVG
100%

着色器程序管线

着色器程序是转换顶点和计算片元颜色的已编译 GPU 代码。WebGLPrograms 子系统基于材质属性和场景上下文管理程序选择、编译和缓存。

程序选择与编译流

SVG
100%

内置着色器库

ShaderLib 为所有标准材质类型提供模板着色器。每个条目包含 uniform 定义、顶点着色器源代码和片元着色器源代码。这些着色器由可重用的 ShaderChunk 模块组成。

ShaderLib 材质类型

ShaderLib 键材质类型光照模型
basicMeshBasicMaterial无光照
lambertMeshLambertMaterialLambertian 漫反射
phongMeshPhongMaterialBlinn-Phong 镜面反射
standardMeshStandardMaterialPBR(金属度/粗糙度)
physicalMeshPhysicalMaterialPBR + 清漆/透射
toonMeshToonMaterial卡通着色
matcapMeshMatcapMaterialMatcap 纹理
pointsPointsMaterial点精灵
dashedLineDashedMaterial虚线
depthMeshDepthMaterial深度编码
normalMeshNormalMaterial法线可视化
distanceMeshDistanceMaterial距点的距离

使用 ShaderChunk 的着色器组合

SVG
100%

状态管理与缓存

WebGLState 类包装所有 WebGL 状态变更调用以最小化冗余 GPU 命令。它跟踪当前状态,仅当期望状态与缓存状态不同时发出 GL 调用。

缓存状态类别

SVG
100%

资源上传与缓存

几何体和纹理数据必须在渲染前上传到 GPU 内存。渲染器维护单独的子系统来管理这些资源并进行智能缓存。

资源管理子系统

上传目标缓存策略
WebGLAttributes顶点缓冲区对象(VBO)按 BufferAttribute.uuid
WebGLGeometries完整几何体按 BufferGeometry.id + 属性版本
WebGLTextures纹理数据按 Texture.id + 源版本 + 参数
WebGLRenderTarget帧缓冲区对象(FBO)按渲染目标实例
WebGLCubeMaps立方体环境贴图按纹理实例与 PMREMGenerator
WebGLCubeUVMaps立方体UV环境贴图按纹理实例,管理生命周期

纹理上传流

SVG
100%

渲染列表与排序

渲染前必须遍历场景图以构建可渲染对象列表。WebGLRenderLists 系统将对象组织为不透明和透明组,然后对它们进行排序以获得正确的渲染顺序。

渲染列表填充

SVG
100%

排序策略

对象类型主要排序次要排序方向
不透明renderOrder 然后 material.idz(深度)从前到后(优化)
透明renderOrderz(深度)从后到前(正确性)

透明对象必须从后到前渲染以获得正确的 alpha 混合。不透明对象从前到后渲染以利用早期深度测试并减少过度绘制。

后端对比:WebGL vs WebGPU

Three.js 支持两种不同架构的渲染后端。WebGL 后端成熟且可用于生产,而 WebGPU 代表具有计算着色器支持的下一代 GPU API。

架构差异

方面WebGLRendererWebGPU 渲染器
API 版本仅 WebGL 2.0(自 r163)WebGPU(Chrome 113+)
着色器语言GLSL ES 3.0WGSL
材质系统传统属性基于节点的材质(TSL)
状态管理全局状态机(缓存)命令编码器(无状态)
计算着色器不支持完全支持
构建输出three.module.jsthree.webgpu.js, three.tsl.js
坐标系Y 向上,右手系可配置

WebGPU 架构(简要,详见WebGPU 与节点材质

WebGPU 后端使用根本不同的方法:

  • 节点材质:通过节点图而非简单属性定义材质属性
  • 渲染束:重复绘制的预录制命令序列
  • 计算通道:用于物理、粒子、后处理的 GPU 计算着色器
  • 多渲染目标:原生支持同时渲染到多个纹理

初始化与上下文创建

渲染器必须在开始渲染前获取 WebGL 上下文并初始化所有子系统。此过程包括能力检测、扩展加载和子系统实例化。

渲染器初始化序列

SVG
100%

上下文属性

渲染器在构造时请求具有特定属性的 WebGL2 上下文:

// 来自 WebGLRenderer 构造函数
const contextAttributes = {
    alpha: true,
    depth: true,
    stencil: false,
    antialias: false,
    premultipliedAlpha: true,
    preserveDrawingBuffer: false,
    powerPreference: 'default',
    failIfMajorPerformanceCaveat: false,
};

材质到着色器映射

不同材质类型需要不同着色器程序。WebGLPrograms 系统分析材质属性和场景上下文以生成适当的着色器代码。

材质类型到 ShaderLib 映射

SVG
100%

着色器变体生成

对于每个材质类型,可能基于以下条件生成数百种着色器变体:

  • 纹理使用(map、normalMap、roughnessMap 等)
  • 光照配置(光源数量和类型)
  • 特性标志(雾效、阴影、形态目标、蒙皮)
  • 材质属性(透明度、双面等)

MeshStandardMaterial 的参数组合示例:

// 在 WebGLPrograms.getParameters() 中生成
{
    map: true,
    normalMap: true,
    roughnessMap: true,
    metalnessMap: true,
    envMap: true,
    lights: true,
    shadowMapEnabled: true,
    numDirLights: 2,
    numPointLights: 3,
    // ... 更多参数
}

每个唯一组合产生不同的已编译着色器程序。

渲染目标系统

渲染目标允许渲染到离屏纹理而非画布。这支持多通道渲染、后处理效果、阴影图和环境贴图生成。

WebGLRenderTarget 结构

渲染目标包含:

  • 一个或多个颜色纹理(附件)
  • 可选深度缓冲区(渲染缓冲区或纹理)
  • 可选模板缓冲区
  • 尺寸和像素格式规范

渲染目标使用模式

SVG
100%

常见渲染目标应用

用例配置消费者
阴影图深度纹理,单通道WebGLShadowMap 生成,材质采样
后处理RGBA 颜色纹理效果读取前一帧输出
反射贴图立方体渲染目标(6面)材质上的环境映射
拾取对象 ID 的整数格式鼠标交互/选择
多重采样MSAA 采样 > 1无后处理的抗锯齿

性能监控

WebGLInfo 对象跟踪对性能分析和调试有用的渲染统计。它计数绘制调用、几何体上传、纹理上传和着色器编译。

WebGLInfo 统计

// 通过 renderer.info 访问
{
    memory: {
        geometries: 42,  // 已上传的 BufferGeometry 数量
        textures: 18     // GPU 上的 Texture 数量
    },
    render: {
        calls: 156,      // 此帧的绘制调用数量
        triangles: 84320,  // 渲染的总三角形数
        points: 0,
        lines: 0,
        frame: 0         // 帧计数器
    },
    programs: [...]  // 已编译 WebGLPrograms 数组
}

通过监控 render.callsrender.triangles,开发者可以识别性能瓶颈。高绘制调用计数表明场景过度碎片化,而高三角形计数表明几何体复杂性。

总结

Three.js 渲染架构组织为协作将场景图转换为渲染像素的模块化子系统:

  1. WebGLRenderer 编排整体渲染过程并拥有所有子系统
  2. WebGLPrograms 基于材质/场景参数管理着色器选择、编译和缓存
  3. WebGLState 包装 GL 状态变更以最小化冗余 GPU 命令
  4. WebGLGeometriesWebGLTextures 处理资源上传和缓存
  5. WebGLRenderLists 组织对象以进行具有适当排序的高效渲染
  6. WebGLRenderStates 累积每场景/相机的光照信息
  7. WebGLShadowMap 通过仅深度渲染通道实现阴影映射

此架构实现高性能渲染,同时为多样材质类型和渲染技术保持灵活性。缓存和状态管理层确保即使在复杂场景中也能最小化 GPU 开销。

有关每个子系统的实现细节,见子页面:WebGL 渲染管线着色器程序与 ShaderLib状态与资源管理阴影映射WebGPU 与节点材质