ARTICLE DETAIL

资讯详情

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

three.js TSL SharpenNode:基于 RCAS 对比度自适应锐化后处理节点的实现原理与实战指南

three.js TSL SharpenNode:基于 RCAS 对比度自适应锐化后处理节点的实现原理与实战指南 three.js TSL SharpenNode基于 RCAS 对比度自适应锐化后处理节点的实现原理与实战指南【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.jsSharpenNode 是 three.js 中 TSLThree Shading Language后处理体系里的一个显示类节点display node用于对场景渲染结果执行 RCASRobust Contrast-Adaptive Sharpening鲁棒对比度自适应锐化后处理。本文基于其官方文档页与源码实现完整讲解sharpen()的导入方式、构造参数与属性、底层 RCAS 算法在 TSL 中的实现细节以及它在仓库示例中配合 TAAU 上采样、TAA 反走样使用的真实接法帮助你在 WebGPU 渲染管线中为低分辨率渲染输出加上一层可实时调节、噪声感知的锐化。节点定位与继承关系SharpenNode 的继承链为EventDispatcher→Node→TempNode→SharpenNode从源码结构看examples/jsm/tsl/display/SharpenNode.js它继承自 TempNode并在构造时声明输出类型为vec4。它不是直接内联进场景材质的普通计算节点而是一个独立的后处理 Pass 节点节点内部持有一个私有的RenderTarget每帧在updateBefore()中把整个效果渲染到该目标再通过passTexture将结果暴露为一个PassTextureNode供下游管线采样。其文档注释明确说明这是Post processing node for contrast-adaptive sharpening (RCAS)算法参考 AMD 的 FidelityFX Super ResolutionFSR项目。它位于examples/jsm/tsl/display/目录下与BloomNode.js、SSAANode.js、TAAUNode.js、TRAANode.js等同属一组 display 类后处理节点。导入方式SharpenNode 是一个 addon需要显式导入参考 官方文档页 中的 Import 说明addons 的安装方式见 three.js 安装文档的 Addons 一节import { sharpen } from three/addons/tsl/display/SharpenNode.js;注意导出的是一个 TSL 函数sharpen而不是SharpenNode类本身。从源码看SharpenNode.js 尾部export const sharpen ( node, sharpness, denoise ) new SharpenNode( convertToTexture( node ), sharpness, denoise );sharpen()内部先对输入 node 调用convertToTexture()把任意Nodevec4输入归一化为纹理节点再构造SharpenNode。这意味着你可以把任何 vec4 节点场景 Pass、其他后处理节点的结果等直接作为输入而不必自己包一层纹理。构造函数与参数new SharpenNode( textureNode, sharpness 0.2, denoise false )参数类型默认值说明textureNodeTextureNode必填效果输入的纹理节点sharpnessNode.float0.2锐化强度。语义注意是反向的0 最大锐化2 无锐化denoiseNode.boolfalse是否在噪声区域衰减锐化强度sharpness的取值语义是理解该节点的关键数值越小锐化越强。这一点在源码中可以直接印证——构造器用nodeObject( sharpness )把参数包装成可求值的节点SharpenNode.js L58而在片段计算中锐化系数由指数映射得出const con exp2( -sharpness ); // sharpness0 → con1最大权重sharpness2 → con0.25即con 2^(-sharpness)sharpness 0时得到满权重sharpness增大后权重按 2 的幂衰减2附近锐化基本消失。文档给出的默认值0.2对应con ≈ 0.87即默认就带较明显的锐化。denoise默认为false开启后节点会用局部亮度统计量计算一个噪声抑制因子nzFactor在噪声高频抖动区域自动削弱锐化权重避免锐化放大噪声。属性.sharpness : Node.float— 锐化强度默认0.2。由于是 Node 类型可以在运行时直接改.value实现实时调节。.denoise : Node.bool— 噪声衰减开关默认false。.textureNode : TextureNode— 效果输入的纹理节点。.isSharpenNode : boolean (readonly)— 类型测试标志恒为true。.updateBeforeType : string— 默认frame即NodeUpdateType.FRAME。因为该节点的效果需要每帧渲染一次所以它注册在帧更新阶段执行updateBefore()而不是延迟到 shader 构建阶段。该属性覆盖自 TempNode。方法.getTextureNode() : PassTextureNode— 返回效果结果的纹理节点把它接到下游管线即可例如赋给renderPipeline.outputNode。.setSize( width, height )— 设置效果输出尺寸像素。实际上无需手动调用节点每帧会用渲染器的drawingBufferSize自动调整内部 RenderTarget 尺寸保证与输出分辨率一致。.setup( builder ) : PassTextureNode— 由节点构建器调用用于生成该 Pass 的 TSL 代码创建NodeMaterial、绑定fragmentNode为 RCAS 函数、记录输入纹理节点。.updateBefore( frame )— 每帧执行一次保存并重置渲染器状态 → 按当前绘制缓冲区尺寸调整 RenderTarget → 以共享QuadMesh全屏绘制锐化 Pass → 恢复渲染器状态。.dispose()— 释放内部RenderTarget与NodeMaterial效果不再需要时必须调用避免 GPU 资源泄漏。RCAS 算法的 TSL 实现解析setup()中定义的rcas函数SharpenNode.js L174-L235是从 AMD FidelityFX FSR 1ffx_fsr1.h移植而来的 RCAS 实现。其核心步骤5 采样十字形邻域通过textureLoad对输入纹理做整数像素级采样取中心像素e与上b、左d、右f、下h四个邻域而不是依赖纹理单元的双线性采样。近似亮度luma b (g r) * 0.5luma 的 2 倍近似权重 0.25 / 0.5 / 0.25 的整数化形式用于后续噪声统计。用户锐化系数con exp2(-sharpness)作为用户参数映射到实际权重。对比度极限Limiter取环域 RGB 最小值mn4与最大值mx4按 FSR 原始公式计算hitMin/hitMax得到自适应的 lobe 权重。源码中RCAS_LIMIT 0.25 - 1.0 / 16.0即 0.1875最终 lobe 被钳制在[-0.1875, 0]区间再乘以con——这个下限防止极端锐化产生振铃ringing。噪声衰减nz是四个邻域亮度均值与中心亮度的偏差nzRange是 5 个亮度值的极差nzFactor 1 - saturate(|nz| / max(nzRange, 1/65536)) * 0.5。当denoise为true时用nzFactor削弱 lobe使噪声区域锐化趋近于零。解析Resolveresult ( (b d f h) * effectiveLobe e ) / ( effectiveLobe * 4 1 )即邻域加权和与中心像素的归一化混合effectiveLobe越负锐化越强时邻域贡献权重越大最终输出vec4(result, e.a)保留原始 alpha。这一实现有几个工程细节值得注意内部RenderTarget使用HalfFloatType且不带深度缓冲L74-L75保证 HDR 数据在 Pass 间流转不丢精度textureLoad要求输入是可直接整数采样的渲染目标纹理这也是sharpen()入口要先convertToTexture的原因之一。仓库示例中的真实用法与 TAAU 上采样配合推荐场景webgpu_upscaling_taau.html 展示了 SharpenNode 最典型的应用低分辨率场景 Pass → TAAU 时域抗锯齿上采样 → RCAS 锐化。关键接法import { sharpen } from three/addons/tsl/display/SharpenNode.js; const scenePassColor scenePass.getTextureNode( output ).toInspector( Color ); const taauNode taau( scenePassColor, scenePassDepth, scenePassVelocity, camera ); const sharpenNode sharpen( taauNode.getTextureNode(), params.sharpness ); // 用 GUI 开关切换是否启用锐化 renderPipeline.outputNode params.sharpening ? sharpenNode : taauNode; renderPipeline.needsUpdate true;该示例的 GUI 提供sharpening布尔开关和sharpness滑块范围 0–2、步长 0.05运行时通过sharpenNode.sharpness.value value实时调整强度示例 L159-L164。这演示了两个实践要点切换sharpenNode是否接入renderPipeline.outputNode后必须置renderPipeline.needsUpdate true触发管线重建调节强度只需写sharpness.value无需重建管线。与 TAA 反走样配合SSR 去噪管线webgpu_postprocessing_ssr_denoise.html 中锐化作为整条后处理链的最后一步加在 TAA 之后function applyPostProcessing( source ) { return sharpen( traa( applyGrading( source ), scenePassDepth, scenePassVelocity, camera ), 0 ); }这里sharpness直接传0即满强度锐化——这是上采样后补偿模糊的典型参数选择时域抗锯齿在平滑噪点的同时会让画面发软RCAS 在对比度受限的前提下把边缘重新拉锐。使用建议与注意事项适用前提SharpenNode 位于three/addons/tsl/display/依赖 TSL 与 WebGPU 渲染器three/webgpu环境在纯 WebGL 后处理EffectComposer 体系中不可直接使用。参数方向易错sharpness是越小越锐。默认0.2已经很锐做 TAAU/TAA 上采样补偿时示例常用0最大日常场景按 0–1 区间调节即可。噪声重的输入请开 denoise如果输入来自低采样或高噪点路径如未充分时域滤波的 SS 结果传入denoise true可让噪声区域自动降低锐化。生命周期管理节点持有独立的 RenderTarget 与 NodeMaterial场景卸载或管线重建时调用dispose()释放 GPU 资源尺寸无需手动管理节点每帧按drawingBufferSize自适应。文档与源码索引官方 API 文档见 docs/pages/SharpenNode.html.md实现源码见 examples/jsm/tsl/display/SharpenNode.js基类行为见 src/nodes/core/TempNode.js。【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表