three.js Renderer 基类完全指南:Node 架构下统一 WebGPU/WebGL 的渲染器 API 全解析
本指南以 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 渲染器体系:
- src/renderers/common/Renderer.js:
Renderer基类本体(约 4000 行,文档标注的 Source 即指向此文件); - src/renderers/webgpu/WebGPURenderer.js 与 WebGPURenderer.Nodes.js:均为
class WebGPURenderer extends Renderer的具体实现。
这里的关键架构变化是: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);NodeManager、NodeLibrary:负责材质、灯光等在节点系统中的表示;Attributes、Geometries、Textures:管理顶点属性、几何体与纹理的 GPU 上传;Pipelines、Bindings、RenderObjects:管理渲染管线、资源绑定与渲染对象;RenderLists、RenderContexts:管理渲染列表与渲染上下文;Animation:驱动内部动画循环;Info:统计 GPU 内存与渲染过程信息;Background:处理场景背景的绘制;InspectorBase:提供渲染器内部状态检查能力;Lighting、XRManager、ClippingContext等作为支撑组件。
理解这些模块的职责有助于理解后文各个属性(如 .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 |
当 antialias 为 true 时默认使用 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)在基类基础上增加了 forceWebGL 与 outputType 两个专属选项,并让 .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):
- 缓存
_initPromise,重复调用返回同一个 Promise,避免二次初始化; - 调用
await backend.init( this )初始化后端(创建 GPU 设备 / GL 上下文); - 若后端初始化失败且注册了
getFallback,则切换到回退后端重新初始化; - 依次创建内部模块
NodeManager、Animation、Attributes、Background、Geometries、Textures、Pipelines、Bindings、RenderObjects、RenderLists、RenderBundles、RenderContexts; - 启动内部动画循环(
_animation.start()),置_initialized = true,初始化 Inspector; - 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),由渲染器自动创建(源码中由CanvasTarget经backend.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 均为逻辑像素;既支持四个参数,也支持传单个四维向量。minDepth与maxDepth仅 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 的签名与文档结构中可以观察到,渲染系统把裁剪信息封装为独立的 ClippingContext(src/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有三种形式:- 单个 number,代表元素数量(count);
- 数组
[x, y, z],代表三维调度大小; - 一个
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.js 与StorageBufferAttribute类)。.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:定义材质、灯光、色调映射函数等库对象如何映射到节点类型。文档指出其必要性:尽管MeshBasicMaterial、PointLight之类的实例可以出现在场景图中,但为了进一步处理,它们内部会被表示为节点。子类WebGPURenderer会将其替换为能力更完整的StandardNodeLibrary。.lighting : Lighting:管理灯光的类 Map 数据结构。.inspector : InspectorBase:Inspector 实例(内部由_inspector.setRenderer( this )关联渲染器)。文档指出任意继承自InspectorBase的类均可作为 inspector,仓库中还配套了面向 devtools 的工具(见 devtools 目录)。.debug : DebugConfig:渲染器调试配置。.shadowMap : ShadowMapConfig:渲染器阴影配置(由渲染器子类 / 使用方配置阴影类型、是否启用等,构造函数中可看到PCFShadowMap、VSMShadowMap等相关常量被导入使用)。.xr : XRManager:渲染器的 XR 管理器,管理 WebXR 会话与渲染(Options 中的multiview即用于 WebXR 多视图路径)。.backend : Backend:当前后端的引用。
十五、精度控制与坐标系
.highPrecision : boolean:启用模型视图 / 法线视图矩阵的高精度计算——开启时使用 CPU 64 位精度换取更高精度,关闭时使用 GPU 32 位换取更高性能。文档特别警告:64 位精度与InstancedMesh、SkinnedMesh不兼容(因为实例化与蒙皮需要 GPU 上一致的矩阵表达)。文档中该属性同时给出了读写两种语义(setter 启用/禁用,getter 返回是否启用)。相关实现可在 src/nodes/accessors/ModelNode.js 中看到highpModelViewMatrix、highpModelNormalViewMatrix等访问器的引入。.coordinateSystem : number(readonly):坐标系,取决于所选后端,值为THREE.WebGLCoordinateSystem或THREE.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 中按图索骥,真正理解每个属性与方法背后的实现。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00