首页
/ three.js Renderer 基类完全指南:Node 架构下统一 WebGPU/WebGL 的渲染器 API 全解析

three.js Renderer 基类完全指南:Node 架构下统一 WebGPU/WebGL 的渲染器 API 全解析

2026-09-07 22:00:00作者:郜逊炳

本指南以 three.js 文档中的 Renderer 参考页 为骨架,深入解读节点式渲染架构中所有渲染器的公共基类 Renderer。它面向想要掌握现代 three.js 渲染管线、从 WebGLRenderer 平滑迁移到基于 Backend 架构的开发者,讲解构造参数 Options、渲染生命周期(init / setAnimationLoop / render / dispose)、清屏、MSAA、色调映射、色彩空间、Compute 计算、像素回读与渲染目标管理等核心能力,并结合仓库源码 src/renderers/common/Renderer.js 揭示底层实现原理。

一、Renderer 在 three.js 中的角色定位

1.1 一切现代渲染器的公共基类

Renderer 是一个“基础渲染器类”(Base class for renderers),官方 API 参考对其定义非常简短,但它在当前 three.js 代码库中的地位极其核心:所有新的渲染器实现都继承自它。从源码中可以看到,当前项目中的具体子类是 WebGPU 渲染器体系:

这里的关键架构变化是:Renderer 本身不再直接接触 WebGL API,而是把平台相关的底层操作全部抽象到 Backend(后端)。文档在构造函数签名中明确写明了这一分工:

new Renderer( backend : Backend, parameters : Renderer~Options )

即渲染器面向的是一个 Backend 实例。从 WebGPURenderer.js 的构造函数可以看出它的默认策略:优先创建 WebGPUBackend,同时通过 parameters.getFallback 注册一个回退工厂,在 WebGPU 不可用时自动降级到 WebGLBackend(WebGL 2),并在控制台打印提示:

parameters.getFallback = () => {
    warn( 'WebGPURenderer: WebGPU is not available, running under WebGL2 backend.' );
    return new WebGLBackend( parameters );
};

因此,本文要讲的 Renderer 基类的所有属性与方法,实际上就是 WebGPURenderer 乃至整个后端无关渲染体系的公共契约。文档中很多属性标注为 readonly 或带默认值,这些默认值全部在基类构造器中初始化(见源码 Renderer.js 区域)。

1.2 渲染器内部协作架构(由源码推断)

Renderer 构造器与 init() 方法维护的私有模块列表可以看出渲染一帧所需的完整协作链,这些模块大多位于 src/renderers/common/ 目录:

  • CanvasTarget:管理输出画布(HTML canvas 或 OffscreenCanvas);
  • NodeManagerNodeLibrary:负责材质、灯光等在节点系统中的表示;
  • AttributesGeometriesTextures:管理顶点属性、几何体与纹理的 GPU 上传;
  • PipelinesBindingsRenderObjects:管理渲染管线、资源绑定与渲染对象;
  • RenderListsRenderContexts:管理渲染列表与渲染上下文;
  • Animation:驱动内部动画循环;
  • Info:统计 GPU 内存与渲染过程信息;
  • Background:处理场景背景的绘制;
  • InspectorBase:提供渲染器内部状态检查能力;
  • LightingXRManagerClippingContext 等作为支撑组件。

理解这些模块的职责有助于理解后文各个属性(如 .info.library.lighting)的含义。

二、构造函数与 Options 参数全解析

2.1 参数说明

  • backend : Backend —— 渲染器所面向的后端,例如 WebGPU 或 WebGL 2(文档原文示例)。基类构造器把它直接保存为公开只读属性 .backend
  • parameters : Renderer~Options —— 配置参数对象,全部可选,均带默认值。

2.2 Options 配置项速查表

基类构造器在源码中通过解构赋值统一接收这些选项(见 Renderer.js),下表汇总了文档 Options 类型定义中的全部字段:

选项 类型 默认值 说明
logarithmicDepthBuffer boolean false 是否启用对数深度缓冲(readonly)。
reversedDepthBuffer boolean false 是否启用反向深度缓冲(readonly)。
alpha boolean true 默认帧缓冲(代表画布最终内容)是透明还是不透明。
depth boolean true 默认帧缓冲是否带深度缓冲。
stencil boolean false 默认帧缓冲是否带模板缓冲。
antialias boolean false 是否以 MSAA 作为默认抗锯齿。
samples number 0 antialiastrue 时默认使用 4 个采样;可设为任何非 0 整数覆盖默认值。
getFallback function null 主后端不可用时的回退后端工厂回调。
outputBufferType number HalfFloatType 输出缓冲类型。默认 HalfFloatType 兼顾最佳质量;为省内存与带宽可改用 UnsignedByteType,但会降低画质。
multiview boolean false true 时,若支持则 WebXR 渲染期间使用多视图渲染。

2.3 源码级细节:这些选项如何生效

有几个选项值得从实现层面说明,因为它们的行为与直觉略有出入:

MSAA 采样数的计算。源码中的实际逻辑是:

this._samples = samples || ( antialias === true ? 4 : 0 );

samples 显式非 0 时优先用它;否则 antialias: true 会启用 4 倍 MSAA。对外暴露的 .samples 属性默认 0

透明画布的清除色。构造器根据 alpha 决定默认清除色的 Alpha 通道:

const alphaClear = this.alpha === true ? 0 : 1;
this._clearColor = new Color4( 0, 0, 0, alphaClear );

也就是说,alpha: true(默认)时画布初始为全透明黑色,便于与页面背景合成;alpha: false 时初始清除为不透明黑色。

子类会覆盖默认选项集WebGPURenderer 的 Options 文档(见 WebGPURenderer.js)在基类基础上增加了 forceWebGLoutputType 两个专属选项,并让 .library 使用功能更全的 StandardNodeLibrary。这说明基类 Options 是所有渲染器共享的最小公共子集。

2.4 同时初始化的一组状态属性

构造器会同步建立多个文档中列出的属性并赋予默认值,包括:

  • .autoClear / .autoClearColor / .autoClearDepth / .autoClearStencil 均为 true
  • .outputColorSpace = SRGBColorSpace.toneMapping = NoToneMapping.toneMappingExposure = 1.0
  • .sortObjects = true
  • .info = new Info().contextNode = context().library = new NodeLibrary().lighting = new Lighting()
  • 私有清除值 _clearDepth = 1_clearStencil = 0
  • 私有状态 _renderTarget = null_activeCubeFace = 0_activeMipmapLevel = 0_outputRenderTarget = null_mrt = null_renderObjectFunction = null 等;
  • 默认画布目标 _canvasTarget = new CanvasTarget( backend.getDomElement() ),渲染器会自动为该画布监听 resize 事件。

三、渲染生命周期:init / setAnimationLoop / render / dispose

文档对渲染器“何时可用”有明确约定,这对应源码里一条非常清晰的调用链。

3.1 必须手动 await renderer.init() 的场景

文档在 render() 方法中强调:只有在渲染器已初始化后才能调用 render();当把 render() 放进由 setAnimationLoop() 定义的动画循环中时,渲染器保证已初始化;而在按需渲染(on-demand)等其他场景,必须先手动调用 init()

从源码可见,render() 在未初始化时会直接抛出异常(Renderer.js):

render( scene, camera ) {
    if ( this._initialized === false ) {
        throw new Error( 'THREE.Renderer: .render() called before the backend is initialized. Use "await renderer.init();" before rendering.' );
    }
    this._renderScene( scene, camera );
}

3.2 init() 内部到底做了什么

init() 是一个幂等的异步初始化(源码 Renderer.js):

  1. 缓存 _initPromise,重复调用返回同一个 Promise,避免二次初始化;
  2. 调用 await backend.init( this ) 初始化后端(创建 GPU 设备 / GL 上下文);
  3. 若后端初始化失败且注册了 getFallback,则切换到回退后端重新初始化;
  4. 依次创建内部模块 NodeManagerAnimationAttributesBackgroundGeometriesTexturesPipelinesBindingsRenderObjectsRenderListsRenderBundlesRenderContexts
  5. 启动内部动画循环(_animation.start()),置 _initialized = true,初始化 Inspector;
  6. resolve 返回渲染器实例 this

对应的只读属性 .initialized、方法 .hasInitialized() 都用于判断当前状态。

3.3 动画循环的正确打开方式

文档强烈建议:动画循环始终用 setAnimationLoop( callback ) 定义,而不是手写 requestAnimationFrame(),以获得最佳兼容性(包括 WebXR 支持)。回调类型在文件末尾被定义为 onAnimationCallback,其签名为 ( time : DOMHighResTimeStamp, frame? : XRFrame )

源码中的 setAnimationLoop() 也会在必要时自动补一次初始化(Renderer.js):

async setAnimationLoop( callback ) {
    if ( this._initialized === false ) await this.init();
    this._animation.setAnimationLoop( callback );
}

使用示例(按需渲染 + 手动 init 的范式):

const renderer = new WebGPURenderer();
await renderer.init();                 // 先初始化
renderer.render( scene, camera );      // 之后才可以渲染

循环渲染的范式:

renderer.setAnimationLoop( ( time ) => {
    mesh.rotation.y = time / 1000;
    renderer.render( scene, camera );
} );

配套方法 .getAnimationLoop() 用于取回当前循环回调。当传给 setAnimationLoop 的回调为 null 时即停止循环。

3.4 资源释放:dispose()

文档说明:当应用不再使用渲染器时,应调用 .dispose() 释放全部内部资源。从实现上看(Renderer.js),它会依次释放 info、内部动画、渲染对象、几何体、管线、节点管理器、绑定、渲染列表、渲染上下文、纹理缓存,各 canvas 对应的内部帧缓冲目标、后端的 timestamp query pool 等,最后调用 setAnimationLoop( null ) 停止循环。

四、帧缓冲与渲染目标体系

文档中围绕“往哪里画”定义了完整的一族 API。理解这套体系需要区分几个概念。

4.1 默认帧缓冲 vs 自定义帧缓冲

  • .domElement:渲染器正在绘制的画布元素(HTMLCanvasElement | OffscreenCanvas),由渲染器自动创建(源码中由 CanvasTargetbackend.getDomElement() 取得并暴露)。
  • render( scene, camera ) 的目标要么是默认帧缓冲(即画布),要么是 setRenderTarget() 指定的自定义帧缓冲
  • setRenderTarget( renderTarget, activeCubeFace = 0, activeMipmapLevel = 0 ):将渲染目标切到自定义帧缓冲;传 null 恢复画布输出。后两个参数用于指定要渲染到立方体贴图的哪个面、哪个 mip 层级。
  • 配套读取:getRenderTarget()(无目标时返回 null)、getActiveCubeFace()getActiveMipmapLevel()

4.2 画布目标与输出渲染目标

  • .setCanvasTarget( canvasTarget ) / .getCanvasTarget():画布目标负责管理渲染器绘入的 HTML canvas 或 OffscreenCanvas。基类构造器已自动创建默认 CanvasTarget(_canvasTarget.isDefaultCanvasTarget = true)。
  • .setOutputRenderTarget( renderTarget ) / .getOutputRenderTarget():输出渲染目标。与普通 setRenderTarget 不同,它代表“最终要呈现”的目标;设置后,内部用于色调映射 / 色彩空间转换的中间缓冲会以它的尺寸为准(源码 _getFrameBufferTarget() 中可见,Renderer.js)。
  • .getCanvasTarget() 返回当前画布目标;.getContext() 返回底层渲染上下文(GPUCanvasContext | WebGL2RenderingContext)。

4.3 MRT(多渲染目标)

  • .setMRT( mrt : MRTNode ) : Renderer 设置 MRT 配置并返回渲染器自身(支持链式调用);.getMRT() 取回当前 MRT 配置。

4.4 内部帧缓冲与 needsFrameBufferTarget

  • .needsFrameBufferTarget:当需要进行色调映射或色彩空间转换时才为 true;为真时渲染器会分配一个内部渲染目标(源码 _getFrameBufferTarget() 中创建 new RenderTarget( width, height, { ... type: this._outputBufferType, samples: this.samples } ))。
  • 文档与源码都指出:与旧的 WebGLRenderer 不同,这里的色调映射与色彩空间转换是单独一遍全屏后处理(fullscreen quad pass)完成的,而不是内联在渲染管线里,从而获得更正确的结果。
  • .currentColorSpace.currentToneMapping 分别表示当前生效的色彩空间与色调映射。文档特别提示:当输出不是面向屏幕时,色彩空间恒为工作色彩空间(working color space),色调映射恒为 NoToneMapping——即这些转换只在最终输出阶段施加。

4.5 画布缓冲能力选项

  • .alpha:默认帧缓冲是否透明(默认 true),由 Options 传入;
  • .depth:默认帧缓冲是否含深度缓冲(默认 true);
  • .stencil:默认帧缓冲是否含模板缓冲(默认 false);
  • .logarithmicDepthBuffer(readonly,默认 false)与 .reversedDepthBuffer(readonly,默认 false):两种深度缓冲特殊模式,均只能通过构造 Options 开启,不能运行时修改。

五、清除操作:autoClear 与 clear 系列

渲染一帧前“是否自动清屏、清哪些缓冲”由一组开关控制。

5.1 自动清除开关

  • .autoClear(默认 true):在每次 render() 之前是否自动清除当前渲染目标——目标既可能是画布(默认帧缓冲),也可能是当前绑定的渲染目标(自定义帧缓冲)。
  • .autoClearColor / .autoClearDepth / .autoClearStencil(均默认 true):在 autoClear = true 前提下,分别决定是否清除颜色、深度、模板缓冲。

5.2 手动清除 API

手动清除会忽略 autoClear 系属性,即无条件按参数执行:

方法 参数与行为
.clear( color = true, depth = true, stencil = true ) 手动清除颜色 / 深度 / 模板三缓冲。
.clearColor() 仅手动清除颜色缓冲。
.clearDepth() 仅手动清除深度缓冲。
.clearStencil() 仅手动清除模板缓冲。

以上均有对应的 Async 版本:.clearAsync().clearColorAsync().clearDepthAsync().clearStencilAsync(),返回在清除完成后 resolve 的 Promise,但文档明确标注这些 Async 版本已弃用(Deprecated)

5.3 清除值与查询器

  • .setClearColor( color, alpha = 1 ) / .getClearColor( target : Color ) : Color:设置 / 读取清除颜色(get 方法把结果写入传入的 target 对象并返回)。
  • .setClearAlpha( alpha ) / .getClearAlpha():设置 / 读取清除 Alpha。
  • .setClearDepth( depth ) / .getClearDepth():设置 / 读取清除深度(内部默认 1)。
  • .setClearStencil( stencil ) / .getClearStencil():设置 / 读取清除模板值(内部默认 0)。

六、输出缓冲类型、尺寸、像素比与裁剪

6.1 输出缓冲类型

  • .getOutputBufferType() : number 返回输出缓冲类型;.getColorBufferType() 与它等价,但自 r182 起弃用,应改用前者。
  • 默认类型由 Options 的 outputBufferType 决定(默认 HalfFloatType,推荐以获得最佳画质;可用 UnsignedByteType 换内存与带宽,代价是画质下降)。

6.2 尺寸与像素比

  • .setSize( width, height, updateStyle = true ):设置渲染器尺寸(逻辑像素);updateStyle 决定是否同步更新 canvas 的 style 属性。
  • .getSize( target : Vector2 ):返回逻辑像素尺寸,不乘像素比
  • .setPixelRatio( value = 1 ):设置像素比并按需重设画布尺寸。
  • .getPixelRatio():读取像素比。
  • .setDrawingBufferSize( width, height, pixelRatio ):一次性指定宽、高、像素比,绘制缓冲尺寸按文档给出的公式计算:
size.x = width * pixelRatio;
size.y = height * pixelRatio;
  • .getDrawingBufferSize( target : Vector2 ):返回物理像素尺寸,此方法尊重(乘算)像素比

6.3 Viewport 与 Scissor

  • .setViewport( x, y, width, height, minDepth = 0, maxDepth = 1 ):x、y、width、height 均为逻辑像素;既支持四个参数,也支持传单个四维向量。minDepthmaxDepth 仅 WebGPU 支持,用于限制视口深度范围。
  • .getViewport( target : Vector4 ):读取当前视口定义。
  • .setScissor( x, y, width, height ) / .setScissor( vector4 ):设置剪裁矩形(逻辑像素坐标)。
  • .setScissorTest( boolean ) / .getScissorTest():开关 / 查询剪裁测试。

七、MSAA 抗锯齿:samples 与 currentSamples

  • .samples : number(默认 0):MSAA 采样数。当 antialias: true 时构造器会置为 4(见 2.3 节)。
  • .currentSamples : number:当前实际生效的采样数,规则由文档精确说明:
    • 渲染到自定义渲染目标时,采用该渲染目标自身的采样数;
    • 若渲染器需要为色调映射或色彩空间转换分配内部帧缓冲目标,则采样数视为 0
  • .getMaxAnisotropy() : number:查询纹理过滤可用的最大各向异性值。

八、色彩空间与色调映射

  • .outputColorSpace(默认 SRGBColorSpace):定义渲染器的输出色彩空间。
  • .toneMapping(默认 NoToneMapping):定义色调映射算法。
  • .toneMappingExposure(默认 1):色调映射曝光强度。
  • .currentColorSpace.currentToneMapping:当前生效值;非屏幕输出场景下的行为见 4.4 节说明。

这些配置与 Options 中的 outputBufferType 共同决定了最终后处理帧缓冲的创建参数,可在源码 _getFrameBufferTarget() 中交叉验证(Renderer.js)。

九、渲染内容控制与深度细节

9.1 透明、不透明与排序

  • .opaque(默认 true):是否渲染不透明渲染对象。
  • .transparent(默认 true):是否渲染透明渲染对象。
  • .sortObjects(默认 true):渲染前是否对渲染列表排序。文档给出了重要提示:排序用于尽量正确渲染带透明度的对象,但按定义排序并非在所有场景都有效;当应用需要其他透明方案(例如手动控制每个对象的渲染顺序)时,可关闭排序。

配套的深度定制 API 允许替换默认排序算法:

  • .setOpaqueSort( method ) / .setTransparentSort( method ):分别为不透明与透明渲染列表设置自定义排序函数;传 null 恢复默认排序。

9.2 渲染对象函数:控制“每个对象怎么被画”

  • .renderObject( object, scene, camera, geometry, material, group, lightsNode, clippingContext = null, passId = null ):默认渲染对象函数,管理对象渲染生命周期。其中 group 只对使用多材质的对象有意义(代表对应 BufferGeometry 中的 group 条目)。
  • .setRenderObjectFunction( renderObjectFunction ):用自定义函数覆盖默认的 renderObject。文档举例说明典型用法——例如实现“具有某类材质的每个对象先用特定覆盖材质执行一遍预处理 pass”。自定义函数实现内部必须调用 renderObject();传 null 复位。
  • .getRenderObjectFunction():取回当前函数(未设置时返回 null)。

9.3 裁剪(Clipping)上下文

renderObject 的签名与文档结构中可以观察到,渲染系统把裁剪信息封装为独立的 ClippingContextsrc/renderers/common/ClippingContext.js),以支持平面裁剪等场景,默认参数为 null

十、编译预热:消灭“着色器编译卡顿”

10.1 compileAsync / compile

  • .compile( scene, camera, targetScene ).compileAsync() 的别名(返回 Promise)。
  • .compileAsync( scene, camera, targetScene = null ):预编译给定场景中的所有材质,用于规避首次渲染新着色器时的“着色器编译卡顿”(shader compilation stutter)。
    • scene:要预编译的场景或 3D 对象;
    • camera:渲染该场景所用的相机;
    • targetScene:当第一个参数是单个 3D 对象、且打算把它加入某个既有场景时传入;注意目标场景的光照与环境必须在调用前配置好

源码实现(Renderer.js)会在必要时先自动 await this.init(),并且会做一次兼容性收尾:若当前阴影类型为已被移除的 PCFSoftShadowMap,则自动警告并降级为 PCFShadowMap。它还通过保存 / 恢复 nodeFrame 渲染上下文等手段,保证预编译不影响后续正常渲染的缓存键一致。

10.2 纹理预载

  • .initTexture( texture ):初始化给定纹理,适合提前预载纹理,避免首次渲染时因解码与 GPU 上传产生明显卡顿。仅当渲染器已初始化后才可使用
  • .initRenderTarget( renderTarget ):初始化给定的渲染目标。
  • .initTextureAsync( texture ):异步版,同样用于预载,但文档标注为弃用

十一、Compute 计算与 GPU↔CPU 数据回读

基于 WebGPU 的 compute shader 能力是这套渲染器的一大特色,相关 API 如下。

11.1 compute / computeAsync

  • .compute( computeNodes : Node | Array<Node>, dispatchSize = null ):执行单个或一组计算节点。dispatchSize 有三种形式:
    1. 单个 number,代表元素数量(count);
    2. 数组 [x, y, z],代表三维调度大小;
    3. 一个 IndirectStorageBufferAttribute,用于间接调度。
  • 该方法仅在渲染器初始化后才能调用;文档注明,当渲染器未初始化时它会返回一个在计算完成后 resolve 的 Promise(否则返回 undefined)。
  • .computeAsync( computeNodes, dispatchSize = null ):异步版,总是返回计算完成后 resolve 的 Promise。

11.2 GPU 数据回读与同步

  • .getArrayBufferAsync( attribute, target = null, offset = 0, count ):在 compute shader 语境中把存储缓冲属性(storage buffer attribute)的数据从 GPU 传回 CPU。返回 Promise,在数据就绪时以 ArrayBuffer | ReadbackBuffer 形式 resolve(对应 src/renderers/common/ReadbackBuffer.jsStorageBufferAttribute 类)。
  • .waitForGPU():用于让 CPU 等待 GPU 完成其任务(例如 compute 任务),实现 CPU 与 GPU 操作的同步。文档标注该方法已弃用

相关源码可继续阅读 src/renderers/common/IndirectStorageBufferAttribute.js 以了解间接调度属性定义。

十二、纹理拷贝与像素回读

  • .copyFramebufferToTexture( framebufferTexture, rectangle = null ):把当前绑定的帧缓冲内容拷贝进给定纹理。rectangle 为二维(Vector2)或四维(Vector4)向量,定义要拷贝的帧缓冲矩形区域。
  • .copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, srcLevel = 0, dstLevel = 0 ):把源纹理数据拷贝到目标纹理。
    • srcRegion:描述源区域的包围盒,可为二维(Box2)或三维(Box3);
    • dstPosition:目标区域的原点向量,二维或三维;
    • srcLevel / dstLevel:源 / 目标的 mip 层级。
  • .readRenderTargetPixelsAsync( renderTarget, x, y, width, height, textureIndex = 0, faceIndex = 0 ):从给定渲染目标读取像素数据,返回 Promise,resolve 时提供 TypedArray 数据。其中 textureIndex 用于 MRT 渲染目标的纹理索引,faceIndex 用于立方体贴图面。

十三、GPU 能力查询与错误处理

13.1 特性与兼容性探测

  • .hasFeature( name : string ) : boolean:查询当前后端是否支持某特性。渲染器未初始化时恒返回 false
  • .hasFeatureAsync( name : string ) : Promise<boolean>:异步版。文档标注已弃用
  • .hasCompatibility( name : string ) : boolean:查询当前后端是否支持给定兼容性项。
  • .init() 成功后可用 .hasInitialized() 或只读 .initialized 判断状态。

13.2 设备丢失与错误回调

  • .onDeviceLost : function:定义设备 / 上下文丢失时应执行的回调。
  • .onError : function:定义后端“未捕获错误”的处理(例如在 error scope 之外触发的 WebGPU 校验 / 显存不足 / 内部错误)。文档明确说明:应用可覆盖它以在自己的 UI 中暴露错误,而不必让错误一路升级为设备丢失;默认实现是打印到控制台。这在 src/renderers/webgpu 的 GPU 错误轮询机制中尤为重要。

13.3 遮挡查询

  • .isOccluded( object : Object3D ) : boolean:对给定 3D 对象执行遮挡查询,若对象被场景中其他对象完全遮挡则返回 true。可用于视锥剔除之外更精确的可见性判断(例如 LOD 与粒子系统优化)。

十四、面向节点系统与扩展的集成点

渲染器与 three.js 的节点系统(TSL / Node)深度集成,文档中如下属性属于这一类,非常适合需要自定义渲染管线的进阶读者。

  • .contextNode : ContextNode:一个全局上下文节点,存放特定变换或计算的覆盖节点(override nodes)。其 value 是一个对象(Object)。这些节点可用来替换渲染管线中的默认行为——例如全局覆盖某些着色器计算。
  • .library : NodeLibrary:定义材质、灯光、色调映射函数等库对象如何映射到节点类型。文档指出其必要性:尽管 MeshBasicMaterialPointLight 之类的实例可以出现在场景图中,但为了进一步处理,它们内部会被表示为节点。子类 WebGPURenderer 会将其替换为能力更完整的 StandardNodeLibrary
  • .lighting : Lighting:管理灯光的类 Map 数据结构。
  • .inspector : InspectorBase:Inspector 实例(内部由 _inspector.setRenderer( this ) 关联渲染器)。文档指出任意继承自 InspectorBase 的类均可作为 inspector,仓库中还配套了面向 devtools 的工具(见 devtools 目录)。
  • .debug : DebugConfig:渲染器调试配置。
  • .shadowMap : ShadowMapConfig:渲染器阴影配置(由渲染器子类 / 使用方配置阴影类型、是否启用等,构造函数中可看到 PCFShadowMapVSMShadowMap 等相关常量被导入使用)。
  • .xr : XRManager:渲染器的 XR 管理器,管理 WebXR 会话与渲染(Options 中的 multiview 即用于 WebXR 多视图路径)。
  • .backend : Backend:当前后端的引用。

十五、精度控制与坐标系

  • .highPrecision : boolean:启用模型视图 / 法线视图矩阵的高精度计算——开启时使用 CPU 64 位精度换取更高精度,关闭时使用 GPU 32 位换取更高性能。文档特别警告:64 位精度与 InstancedMeshSkinnedMesh 不兼容(因为实例化与蒙皮需要 GPU 上一致的矩阵表达)。文档中该属性同时给出了读写两种语义(setter 启用/禁用,getter 返回是否启用)。相关实现可在 src/nodes/accessors/ModelNode.js 中看到 highpModelViewMatrixhighpModelNormalViewMatrix 等访问器的引入。
  • .coordinateSystem : number(readonly):坐标系,取决于所选后端,值为 THREE.WebGLCoordinateSystemTHREE.WebGPUCoordinateSystem。从源码看它直接转发自 this.backend.coordinateSystem
  • .isRenderer : boolean(readonly,默认 true):类型测试标志。
  • .domElement:见 4.1 节。

十六、统计信息与可观测性

  • .info : Info:保存关于 GPU 内存与渲染过程的一系列统计信息,便于调试与监控。对应实现文件为 src/renderers/common/Info.js,它会在 dispose() 时一并释放。典型用途包括查询 draw call 数量、三角形数、纹理 / 几何体数量、GPU 显存占用等(字段以该文件实际导出为准)。

十七、已弃用 API 汇总(迁移提示)

文档在多处标注了弃用状态,为便于迁移集中列出:

弃用 API 替代方案 / 说明
.renderAsync( scene, camera ) 使用 render()(在 setAnimationLoop 内)或先 await init() 再同步渲染。
.clearAsync() / .clearColorAsync() / .clearDepthAsync() / .clearStencilAsync() 使用对应同步版本 clear() 等。
.hasFeatureAsync( name ) 使用同步 hasFeature()(初始化后查询)。
.initTextureAsync( texture ) 使用 initTexture()
.waitForGPU() 同步 CPU 与 GPU 的方式已被更细粒度的 API 取代。
.getColorBufferType() 自 r182 起弃用,改用 .getOutputBufferType()

十八、完整实战示例

下面给出一个覆盖本文大部分 API 的 Node 风格入门示例(可直接对照仓库中的 webgpu 系列示例manual 文档 阅读),代码以当前仓库的 WebGPURenderer 为基础:

import * as THREE from 'three';
import { WebGPURenderer } from 'three/webgpu'; // 或 'three/addons/renderers/webgpu/WebGPURenderer.js'

const renderer = new WebGPURenderer( {
    antialias: true,            // 默认启用 4x MSAA
    alpha: true,                // 画布透明
    outputBufferType: THREE.HalfFloatType, // 高质量输出缓冲
} );

renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setPixelRatio( window.devicePixelRatio );
document.body.appendChild( renderer.domElement );

await renderer.init();          // 渲染前必须初始化

// 渲染目标(离屏缓冲)
const rt = new THREE.WebGLRenderTarget( 512, 512 );
renderer.setRenderTarget( rt );
renderer.render( scene, camera );
renderer.setRenderTarget( null ); // 回到画布

// 预热材质与纹理,避免首帧卡顿
await renderer.compileAsync( scene, camera );
renderer.initTexture( texture );

// 色调映射与色彩空间
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.0;

// 清屏控制
renderer.autoClear = true;
renderer.setClearColor( 0x000000, 1 );

// 动画循环
renderer.setAnimationLoop( ( time ) => {
    renderer.render( scene, camera );
} );

// 不再使用时释放资源
renderer.dispose();

提示:three/webgpu 入口与 importmap 的具体写法请以仓库内 examples 的真实示例为准;RenderTarget、色彩空间等常量定义可参见 src/constants.js

十九、小结

Renderer 基类用一套“构造参数统一化 + 后端解耦 + 生命周期明确化”的设计,承载了 three.js 从 WebGL 1/2 走向 WebGPU 的全部公共能力:无论底层是 WebGPUBackend 还是 WebGLBackend,开发者面对的都是同一组 init / setAnimationLoop / render / dispose 流程、同一套清除与目标管理、同一种 MSAA / 色调映射 / 色彩空间配置,并且还能拿到 compute、异步回读、遮挡查询、节点级覆盖(contextNode)等高级扩展点。希望本文档能帮助你对照 Renderer.html.md 快速查阅,并到源码 src/renderers/common/Renderer.js 中按图索骥,真正理解每个属性与方法背后的实现。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388