Skip to content

RenderPipeline API(后处理管线)

viewer.renderPipeline 管理渲染后处理链,内置 Bloom、SSGI、SSR、TRAA 支持,并提供自定义后处理覆盖机制。

渲染节点图

Stage 1: pass(scene, camera) + MRT(按需配置 output/emissive/normal/SSR G-buffer/velocity)

Stage 2: 后处理链
    ├─ 内置模式: SSGI → SSR + Temporal Reproject + Denoise → Bloom
    └─ 自定义模式: outputComposer(scenePass) → Node

Stage 3: Output Effects(仅默认/内置模式,插件/扩展追加效果)

Stage 4: TRAA 时间抗锯齿

Stage 5: Overlay Passes(blendColor 叠加 ViewerHelper 等)

outputNode = 最终结果

属性

属性类型说明
scenePassPassNode场景渲染通道节点,pass(scene, camera) 的返回值。
needsUpdateOutputNodeboolean标记输出节点需要在下一帧重建。

Bloom

基于 emissive MRT 通道的泛光效果。

typescript
// 开启 Bloom
viewer.renderPipeline.enableBloom({ strength: 1.5, radius: 0.4, threshold: 0.2 });

// 运行时更新参数
viewer.renderPipeline.updateBloom({ strength: 2.0 });

// 关闭 Bloom
viewer.renderPipeline.disableBloom();

BloomConfig

属性类型默认值说明
strengthnumber1泛光强度
radiusnumber0泛光扩散半径
thresholdnumber0亮度阈值,低于此值不产生泛光

SSGI(屏幕空间全局光照)

仅支持 PerspectiveCamera,使用 OrthographicCamera 时会自动跳过并输出警告。

SSGI 分别生成 AO 与 GI 纹理,并按 scene.rgb × AO + diffuse.rgb × GI 合成最终颜色。AO 只压暗遮蔽区域,GI 只增加间接漫反射;背景不参与 SSGI。Viewer 默认的 reversed depth 和显式配置的标准深度均受支持,应用侧无需转换 depth texture。

在线示例:默认开启的纯 AO

typescript
// 开启 SSGI
viewer.renderPipeline.enableSSGI({ aoIntensity: 1, giIntensity: 10 });

// 运行时更新参数(直接修改 uniform,不重建节点图)
viewer.renderPipeline.updateSSGI({ giIntensity: 20, radius: 8 });

// 关闭 SSGI
viewer.renderPipeline.disableSSGI();

SSGIConfig

属性类型默认值范围说明
sliceCountnumber11–4半球切片数
stepCountnumber121–32每切片采样步数
aoIntensitynumber10–4AO 对遮蔽项的对比度/压暗强度
giIntensitynumber100–100加到漫反射项上的间接光强度
radiusnumber121–25世界空间采样半径
thicknessnumber10.01–10物体厚度(世界单位)

SSR(屏幕空间反射)

SSR 使用 stochastic ray marching 生成反射,随后通过运动向量执行 Temporal Reproject,并使用 Recurrent Denoise 进行时空降噪。完整链路需要连续帧积累,启用后应将 viewer.frameloop 设为 'always'

仅支持 PerspectiveCamera,使用 OrthographicCamera 时会自动跳过并输出警告。

在线示例:SSR 时空降噪

typescript
viewer.frameloop = 'always';

viewer.renderPipeline.enableSSR({
  quality: 0.25,
  maxDistance: 0.4,
  temporal: { maxFrames: 16 },
  denoise: { radius: 1.5, strength: 0.725 },
});

viewer.renderPipeline.updateSSR({
  intensity: 1.2,
  denoise: { radius: 1 },
});

viewer.renderPipeline.disableSSR();

SSRConfig

属性类型默认值说明
resolutionScalenumber1SSR 计算分辨率比例,范围 0–1
qualitynumber0.25Ray marching 采样质量,范围 0–1
mirrorBiasnumber0.5将 stochastic GGX 射线收束到镜面主瓣
maxDistancenumber0.4最大反射追踪距离
intensitynumber1反射强度
thicknessnumber0.1命中厚度容差
maxLuminancenumber35HDR 反射亮度上限
stepExponentnumber3Ray marching 步长分布指数;修改会重编译 SSR 材质
binaryRefinebooleanfalse是否使用二分子步细化命中;修改会重编译 SSR 材质
screenEdgeFadenumber0.2屏幕边缘淡出宽度
screenEdgeFadeBlackbooleantrue边缘和未命中区域是否淡出到黑色;修改会重编译 SSR 材质
temporalSSRTemporalReprojectConfig见下表时域重投影参数
denoiseSSRDenoiseConfig见下表循环降噪参数

SSRTemporalReprojectConfig

属性类型默认值说明
maxFramesnumber16历史累积最大帧数
clampIntensitynumber0.25历史颜色方差裁剪强度
flickerSuppressionnumber1时域闪烁抑制强度
hitPointReprojectionbooleantrue是否启用镜面命中点视差重投影

SSRDenoiseConfig

属性类型默认值说明
lumaPhinumber0.75亮度边缘停止权重
depthPhinumber20深度边缘停止权重
normalPhinumber0.3法线边缘停止权重
roughnessPhinumber100粗糙度边缘停止权重
radiusnumber1.5空间降噪半径
alphaPhinumber5SSR 射线长度边缘停止权重
strengthnumber0.725历史融合强度
adaptnumber0.5自适应历史融合系数
smoothDisocclusionsbooleantrue是否平滑遮挡解除区域
flickerSuppressionnumber1降噪阶段闪烁抑制强度
adaptiveTrustnumber1历史可信度自适应强度

SSR 会增加 ssrDiffusessrNormalvelocity MRT 通道;其中法线/粗糙度与漫反射/金属度分别打包到两个 8-bit 附件中。SSGI 单独启用时使用 ssgiDiffuse,与 SSR 同时启用时则复用 ssrDiffuse.rgb,避免为相同的漫反射数据重复分配 MRT 附件。它可以和 SSGI、Bloom、TRAA 组合,但同时启用仍会增加 MRT 带宽和时域 pass 数量。

默认的 scene.environment 通常是 PMREM 纹理,不能直接作为 SSRNode 的等距柱状 HDR 输入。本封装只叠加屏幕空间命中结果,不修改全局 PhysicalLightingModel

Reversed depth 兼容

Viewer 默认启用 Three.js reversedDepthBuffer。SSGI 会在 clear depth 为 0 时跳过背景像素;SSR 封装会为 SSR、Temporal Reproject 和 Recurrent Denoise 三个内部全屏 pass 补充相同的 reversed-depth 背景像素早退。两者都保留原始 reversed depth 供位置重建、ray marching 和历史深度比较使用。应用侧无需关闭 reversed depth,也不需要转换 depth texture。

如果通过 rendererOptions: { reversedDepthBuffer: false } 使用标准深度,兼容层不会改写 Three.js 原有节点图。

stepExponentbinaryRefinescreenEdgeFadeBlack 属于编译期 SSR 参数,运行时修改会重编译内部 SSR 材质;其余数值参数直接更新 uniform。

性能建议

resolutionScale 只缩放 SSR ray-marching target;Temporal Reproject 和 Recurrent Denoise 仍跟随 renderer 的完整 drawing-buffer 尺寸。在 Retina 屏幕或重型场景中,可在创建 Viewer 时使用 pixelRatio: 1

typescript
const viewer = new Viewer({
  el: document.getElementById('app')!,
  pixelRatio: 1,
});

建议从默认 maxDistance: 0.4 开始调节,并谨慎启用每帧更新的大尺寸动态阴影。frameloop = 'always' 仍是时域重投影和循环降噪正确收敛的必要条件。

TRAA(时间抗锯齿)

基于运动向量的时间分辨率抗锯齿。

typescript
// 开启 TRAA
viewer.renderPipeline.enableTRAA();

// 关闭 TRAA
viewer.renderPipeline.disableTRAA();

自定义后处理(OutputComposer)

使用 setOutputComposer 可完全覆盖内置后处理链,接收 scenePass 返回自定义的 TSL 节点。自定义 composer 会保持最终输出语义,不再叠加插件注册的 output effects。

typescript
import { luminance, vec4 } from 'three/tsl';

// 灰度滤镜
viewer.renderPipeline.setOutputComposer((scenePass) => {
  const color = scenePass.getTextureNode();
  const gray = luminance(color.rgb);
  return vec4(gray, gray, gray, 1.0);
});

// 恢复默认(清除自定义后处理)
viewer.renderPipeline.setOutputComposer(null);

Output Effects

插件可使用 addOutputEffect 在默认/内置后处理链之后追加效果,而不占用业务侧的 setOutputComposer()。如果业务设置了自定义 composer,output effects 会被跳过,由 composer 自己负责完整输出。

typescript
const effect = (scenePass, inputNode) => inputNode;
viewer.renderPipeline.addOutputEffect(effect);
viewer.renderPipeline.removeOutputEffect(effect);

如果 effect 已经调用了 renderOutput(),可设置 effect.includesOutputTransform = true,管线只会在该 effect 实际生效时关闭默认输出变换。

如需额外 MRT 输出通道,可用 addMRTChannel / removeMRTChannel 注册,不会污染核心依赖。

Overlay Passes

用于叠加辅助渲染层(如 ViewerHelper),始终在后处理链之后执行。

typescript
viewer.renderPipeline.addOverlayPass(overlayNode);
viewer.renderPipeline.removeOverlayPass(overlayNode);

u-space docs