十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

three.js WebGPU 渲染管线管理模块 RenderPipeline 完全指南:节点化后处理链的构建与色彩管理

three.js WebGPU 渲染管线管理模块 RenderPipeline 完全指南:节点化后处理链的构建与色彩管理 three.js WebGPU 渲染管线管理模块 RenderPipeline 完全指南节点化后处理链的构建与色彩管理【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.jsRenderPipeline是 three.js 面向WebGPURenderer提供的渲染管线管理模块它负责把 TSL 节点如pass( scene, camera )场景通道编排为完整的渲染输出链与后期处理效果链。读完本文你将掌握如何用RenderPipeline替代传统后处理思路、正确地在动画循环中调用其render()以及如何处理outputColorTransform与renderOutput()所涉及的色调映射、色彩空间等关键配置。模块定位与适用范围RenderPipeline的职责非常明确——管理应用中的渲染管线设置。官方文档 RenderPipeline 参考页 与源码 src/renderers/common/RenderPipeline.js 的注释一致地指出该模块负责管理应用中的渲染管线设置。通常你只会创建该类的一个实例并用它定义渲染管线的输出以及后期处理效果链。需要注意一个硬性前提该模块只能配合WebGPURenderer使用。相应地RenderPipeline被导出在 WebGPU 构建入口中例如 src/Three.WebGPU.js 与 src/Three.WebGPU.Nodes.js 中均有export { default as RenderPipeline }。它不应被用于默认的WebGLRenderer渲染路径。从模块结构上看RenderPipeline与同样位于src/renderers/common/下的DirectRenderPipeline是相互独立的导出类前者在 src/Three.WebGPU.js 中紧随其后导出两者对应不同驱动方式本文聚焦RenderPipeline本身。基本用法从一个 Code Example 说起文档给出的最小示例只有三行const renderPipeline new RenderPipeline( renderer ); const scenePass pass( scene, camera ); renderPipeline.outputNode scenePass;这段代码的语义拆解如下pass( scene, camera )是一个 TSL 函数它把场景 相机的渲染结果封装成一个通道节点。其底层实现在 src/nodes/display/PassNode.jspass ( scene, camera, options ) new PassNode( PassNode.COLOR, scene, camera, options )即创建一个颜色类型的PassNode。相关的 TSL 函数pass、renderOutput等由 src/Three.TSL.js 统一对外导出实际示例中通常写作import { pass, renderOutput } from three/tsl。把该通道节点赋给renderPipeline.outputNode它就作为渲染管线的最终输出。后续要叠加效果时只要把节点链条的最后一环赋给outputNode即可例如const dotScreenPass dotScreen( scenePass ); // 点阵化效果节点 const rgbShiftPass rgbShift( dotScreenPass ); // RGB 分离效果节点 renderPipeline.outputNode rgbShiftPass; // 链条末端作为最终输出这正是 webgpu_postprocessing.html 示例的实际组织方式——多级效果通过 TSL 节点的函数式组合串接起来末尾统一交给outputNode。构造函数与参数new RenderPipeline( renderer : Renderer, outputNode : Nodevec4 )构造一个新的渲染管线管理模块签名与两个参数的含义如下表所示参数类型说明rendererRenderer对渲染器的引用必须为WebGPURendereroutputNodeNodevec4可选输出节点即最终渲染输出的 TSL 节点需要注意一个文档之外的实现细节outputNode参数带有默认值。查看构造函数源码 src/renderers/common/RenderPipeline.jsconstructor( renderer, outputNode vec4( 0, 0, 1, 1 ) ) {默认值是vec4( 0, 0, 1, 1 )——一个不透明的白色四维向量。也就是说即便创建时不传入输出节点管线也会有一个清屏为白色不透明的兜底输出而不是抛出错误。这是从源码可以确认的行为值得在排错时留意。构造函数内部还会完成以下初始化源码 L30-L123设置this.isRenderPipeline trueL39供类型测试使用保存renderer引用、缓存当前renderer.toneMapping与renderer.outputColorSpace创建this.outputColorTransform true、this.needsUpdate true内部构建一张全屏四边形QuadMesh材质为NodeMaterial名称为RenderPipeline后续所有效果最终都会渲染在这张全屏四边形上源码 L84-L95。属性详解.context : Object只读返回当前渲染管线栈的上下文对象。它由_updateContext()构造其结构包含源码 L181-L188const contextData { renderPipeline: this, // 指向管线自身 renderPipelineState: { viewOffsetOwner: null }, onBeforePipelineCallbacks: [], // 管线执行前的回调列表 onAfterPipelineCallbacks: [] // 管线执行后的回调列表 };该对象最终通过 TSL 的context()助手绑定到内部材质的contextNode上源码 L205从而让管线状态在节点图中可被读取。.needsUpdate : Nodevec4当输出节点发生变化时必须设置为true。它的语义可以从_update()方法源码 L216-L240中看到每次调用render()时先执行_update()若renderer.toneMapping或renderer.outputColorSpace相比构造/上次缓存值发生变化会自动把needsUpdate置为true若needsUpdate true则调用_updateContext()重建上下文并立即复位为false。换句话说needsUpdate是驱动内部上下文重建的脏标记默认初始为true源码 L82因为管线在首次render()前必须完成上下文构建。当你动态更换outputNode链后应手动置true通知管线刷新。.outputColorTransform : boolean控制默认的输出色调映射与色彩空间转换是否启用默认值为true源码 L75。为什么需要关闭它文档给出了关键场景某些效果期望在色调映射与色彩空间转换之后执行典型例子是 FXAA 抗锯齿——它需要 sRGB 输入。如果保持默认true管线会自动把输出节点包装为renderOutput( outputNode, toneMapping, outputColorSpace )见_updateContext()源码 L190-L201在效果链末端统一做颜色输出变换而如果你希望把某个效果插在变换之后参与就必须把该标志关掉。当置为false时应用必须自行用RenderOutputNode控制输出变换文档给出的写法是const outputPass renderOutput( scenePass );这一模式在仓库示例中大量出现。例如webgpu_postprocessing_3dlut.html先renderPipeline.outputColorTransform false然后const outputPass renderOutput( scenePass )再对outputPass施加 LUT 3D 调色节点lut3D( ... )最后把调色结果赋给outputNode。这样 3D LUT 是在颜色转换后的标准空间里进行处理的。webgpu_postprocessing_fxaa.html同样先关闭默认变换renderOutput( scenePass )后再接 FXAA 节点。webgpu_lights_clustered.html关闭变换后在输出前混合一个基于热量图的颜色再调用renderOutput( mix( scenePass, heatColor, finalInfluence ) )完成最终变换实现后处理参与后再统一输出的自定义色调处理。webgpu_mrt_mask.html把带遮罩的模糊结果做加法后调用.renderOutput()收尾renderPipeline.outputNode colorPass.add( gaussianBlur( maskPass, 1, 20 ).mul( .3 ) ).renderOutput()。对比之下webgpu_custom_fog_background.html 保持outputColorTransform true并注释说明不应用色调映射仅做默认色彩空间变换——表明该标志同时决定了是否把渲染器当前的色调映射带入节点图。.outputNode : Nodevec4定义渲染管线最终输出的节点通常是效果节点链条中的最后一个。它既可通过构造函数传入也可随时赋值更换见上文 Code Example。从实现角度outputNode最终会成为内部全屏四边形NodeMaterial的fragmentNode源码 L206节点图的输出直接决定屏幕上每一像素的颜色。.renderer : Renderer对渲染器的引用构造时保存供内部渲染使用源码 L46。方法详解.render()当使用RenderPipeline承载渲染管线与后期处理效果时应用必须在动画循环里调用这个版本的render()而不是渲染器自带的render()。其内部流程源码 L130-L160值得展开调用_update()按需重建上下文依次执行contextData.onBeforePipelineCallbacks中的回调临时改写渲染器输出状态把renderer.toneMapping强制设为NoToneMapping、把renderer.outputColorSpace强制设为ColorManagement.workingColorSpace工作色彩空间这是为了防止底层再叠加一次输出变换——最终的颜色变换统一由节点图里的renderOutput包装层负责临时禁用renderer.xr渲染内部全屏四边形_quadMesh随后恢复 XR 状态恢复步骤 3 中被改写的toneMapping与outputColorSpace执行contextData.onAfterPipelineCallbacks中的回调。动画循环中的典型用法取自 webgpu_postprocessing.htmlfunction animate() { object.rotation.x 0.005; object.rotation.y 0.01; renderPipeline.render(); // 用管线的 render而不是 renderer.render( scene, camera ) }注意渲染器通常已通过renderer.setAnimationLoop( animate )启动驱动见 webgpu_postprocessing_3dlut.htmlRenderPipeline只负责把outputNode描述的效果链画到屏幕上。.renderAsync() : Promise已废弃renderAsync()同样是文档中要求应用在动画循环内使用的异步渲染版本但已标记为Deprecated。查看实现源码 L251-L259可以发现废弃原因是 API 演进它会先await this.renderer.init()再调用render()而官方建议改为在使用render()前自行await renderer.init()。async renderAsync() { warnOnce( RenderPipeline: renderAsync() has been deprecated. Use render() and await renderer.init(); when creating the renderer. ); // deprecated r181 await this.renderer.init(); this.render(); }因此在新代码中应遵循建议await renderer.init()之后在动画循环里直接调用renderPipeline.render()。该方法的返回值是一个 Promise当渲染完成时 resolve。.dispose()释放内部资源。实现非常精简源码 L165-L169dispose() { this._quadMesh.material.dispose(); }即释放内部全屏四边形使用的NodeMaterial。当不再需要该管线例如切换场景、销毁渲染器时应调用它避免 GPU 侧材质资源泄漏。深入上下文、色调映射与色彩空间如何协作把上面的实现线索串起来可以得到RenderPipeline的核心数据流你为outputNode赋一条 TSL 节点链scenePass→ 各种效果 → 末端节点_updateContext()读取缓存的toneMapping/outputColorSpace若outputColorTransform true用renderOutput( outputNode, toneMapping, outputColorSpace )自动包裹整条链——这就是默认输出变换的来源若为false则不包裹把toneMapping/outputColorSpace写进contextData交由节点图中的renderOutput自行决定何时变换源码 L190-L201contextData通过context()助手绑定为材质contextNode包装后的链作为fragmentNode整条链由QuadMesh在render()时绘制到屏幕。其中renderOutput本身是RenderOutputNode的 TSL 工厂函数定义在 src/nodes/display/RenderOutputNode.jsrenderOutput ( color, toneMapping null, outputColorSpace null ) new RenderOutputNode( ... )。也就是说自动包裹路径实际上等价于你手动写出renderOutput( scenePass, renderer.toneMapping, renderer.outputColorSpace )。关于该节点更完整的属性与语义可参考 RenderOutputNode 参考页场景通道节点的能力如 MRT、多渲染目标参见 PassNode 参考页。RenderPipeline自己并不直接持有复杂的状态类而更像一个把节点图翻译成一次全屏绘制的调度器。这一点解释了为什么它在 src/renderers/common/ 下实现——它与QuadMesh、材质系统同属通用渲染层对 WebGPU 后端而言所有 effect 最终都只是一次带自定义片元着色器的全屏三角形/四边形绘制。在真实项目中的集成清单综合仓库示例落地一个RenderPipeline后处理方案的完整步骤如下引入构建与 TSL 符号对应各示例顶部 importimport * as THREE from three/webgpu; // 提供 THREE.WebGPURenderer、THREE.RenderPipeline import { pass, renderOutput } from three/tsl; // 提供节点化通道与输出变换创建渲染器并初始化new THREE.WebGPURenderer( { antialias: true } )、setPixelRatio、setSize、setAnimationLoop( animate )并在需要时await renderer.init()webgpu_postprocessing_3dlut.html。创建管线实例const renderPipeline new THREE.RenderPipeline( renderer );。按需配置输出变换若后处理效果应在线性空间执行、由节点图末尾统一做色调映射与色彩空间变换则保留默认outputColorTransform true若某效果如 FXAA、LUT 调色、选择性色调混合需要在变换后执行则置false并用renderOutput( ... )收尾。组装节点链从pass( scene, camera )出发逐级叠加 TSL 效果最后一环赋给renderPipeline.outputNode。动画循环中渲染调用renderPipeline.render()而非renderer.render()。动态更新更换节点链后将needsUpdate置true销毁时调用dispose()。值得一提的是这种节点化渲染管线能力已被仓库内的高阶后处理组件广泛复用——examples/jsm/tsl/display/下的BloomNode、OutlineNode、OITPassNode、TRAANode、GTAONode、TAAUNode等模块内部都会引用RenderPipeline把它们接入场景时的组织方式与上述流程一致可作为更深层的阅读线索。小结RenderPipeline是 three.js WebGPU 渲染路径中节点化后处理的枢纽它以 TSL 节点链定义最终输出用一张全屏四边形承载全部效果并在渲染瞬间托管色调映射与色彩空间变换。正确理解它的四个关键开关——outputNode链条末端、outputColorTransform是否自动做输出变换、needsUpdate上下文刷新脏标记与render()动画循环入口——即可在WebGPURenderer上构建出结构清晰、可维护的任意后期处理管线。官方 API 参考见 RenderPipeline 参考页完整实现见 src/renderers/common/RenderPipeline.js。【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表