TiXL 中 Bloom 泛光算子完全指南:级联降采样模糊算法与参数深度解析
【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3
TiXL(开源实时动态图形创作工具)在Lib.image.fx.blur算子库中提供了Bloom算子,它是对 Glow 的"更通用、更快"的替代方案。本文以算子官方文档为骨架,结合仓库中的 C# 算子定义与配套 HLSL 着色器源码,完整讲解 Bloom 的算法原理、全部输入参数的含义与调参技巧,以及在 PostFX 后期管线中的组合用法。读完本文,你将能够直接上手搭建一套可复制的 Bloom 泛光效果,并理解每个参数在底层着色器中的实际作用。
一、Bloom 是什么:从 Glow 到 Bloom
在 TiXL 的 Lib.image.fx.blur 算子库中,官方对 Bloom 的定位是:
A more versatile and faster version of Glow.
即它是 Glow 的升级形态——用途更广、性能更优。两者的核心思路同源:提取画面中的亮部,生成多层模糊副本,再叠加回原图,从而制造出高光区域向外晕开的光晕效果。区别在于 Bloom 采用了更高效的**降采样 + 模糊级联(down sampling and blurring cascade)**架构:
- 对原始图像进行亮度提取,只保留超过阈值的亮部区域;
- 通过逐级降采样与模糊,生成多张分辨率递减的模糊副本(blur kernel 层);
- 将这些模糊层按梯度(gradient)做加法混合,最终与原始图像合成。
与一次性在全分辨率上做多次模糊的传统做法相比,级联方案中每一级都在更小的纹理上运算,模糊半径对应的采样开销被大幅压缩,这也是 Bloom 比 Glow 更快的原因。
二、算法底层:四个着色器支撑级联流水线
Bloom 的级联流水线并非黑盒。在仓库的Operators/Lib/Assets/shaders/img/blur/目录下,可以找到支撑该算子的六份 HLSL 着色器源码,它们清晰地揭示了每一级模糊层的生成过程:
| 着色器文件 | 阶段职责 |
|---|---|
Bloom-BrightpassPS.hlsl | 亮度提取(Brightpass):只保留超过阈值的亮部 |
Bloom-DownsamplePS.hlsl | 2×2 降采样:每级分辨率减半 |
Bloom-SeparableBlurPS.hlsl | 可分离高斯模糊:横向/纵向两次一维模糊 |
Bloom-UpsamplePS.hlsl | 上采样回更高分辨率 |
Bloom-CopyPS.hlsl | 拷贝/合成辅助 |
Bloom-FullscreenVS.hlsl | 全屏三角形顶点着色器 |
2.1 亮度提取(Brightpass)与ColorWeights/Threshold的对应关系
Bloom-BrightpassPS.hlsl是流水线的第一站,它决定了"哪些像素有资格发光"。核心逻辑如下(节选自Operators/Lib/Assets/shaders/img/blur/Bloom-BrightpassPS.hlsl):
cbuffer ThresholdParams : register(b0) { float3 ColorWeights; float Threshold; }; float4 psMain(PS_INPUT input) : SV_Target { float4 color = SourceTexture.Sample(LinearSampler, input.uv); color = clamp(color, 0, float4(1000,1000,1000,1)); // Calculate brightness (luminance) float brightness = dot(color.rgb, ColorWeights); // Subtract threshold and saturate (keeps positive values, zeros out negative) float contribution = saturate(brightness - Threshold); if (isnan(contribution)) { contribution = 0; color = 0; } return float4(color.rgb * contribution, color.a); }这段代码揭示了两个输入参数的底层机制:
ColorWeights(Vector4):其 RGB 三个分量作为权重,与像素颜色做点积dot(color.rgb, ColorWeights),计算"感知亮度"(luminance)。因此修改这三个分量可以按颜色通道加权——例如只对红色通道的亮部起效,就能限制泛光作用于特定颜色。文档特别注明,其默认值对应 NTSC 标准的颜色感知权重(对红、绿、蓝通道分别加权,接近人眼敏感度)。而第四分量 Alpha 的作用很特殊:把 Alpha 调小,会把这些权重颜色向灰度混合,相当于削弱通道选择性、回归均匀亮度。Threshold(Single):从亮度中减去阈值并saturate,即"只保留超过阈值的正差值,低于阈值的像素输出黑色"。注意这不是硬性二值化(hard step),而是带平滑过渡的软阈值——亮度刚过阈值的像素贡献从 0 平滑上升,避免出现生硬的亮部边缘。着色器还包含isnan防御逻辑,防止 NaN 输入导致整条管线污染。
2.2 级联的降采样环节
Bloom-DownsamplePS.hlsl实现了每一级模糊层的降采样:以目标像素为中心,在源纹理上采样2×2 共四个纹素并取平均(4-tap box filter),输出到宽高各减半的渲染目标。这保证了级联每一级的纹理尺寸严格减半,为后续的分离式模糊提供了廉价的高分辨率前驱。
2.3 从源码到参数:级联的合成方式
每次模糊后得到的层会与GlowGradient相乘,再由GainAndBias塑造各层权重的分布,最终逐层上采样并加法混合(additively combine)回原图。整个过程与文档描述完全一致:"creates multiple blurred copies of the original image and then combines these layers additively while applying a gradient"。
三、输入参数详解(完整参照官方文档)
以下是 Bloom 算子的全部输入参数,在 Bloom.cs 中均有对应的InputSlot定义(含稳定 GUID),供程序化控制与自动化引用:
| 名称(相关度 & 类型) | 说明 |
|---|---|
| Image(Texture2D,必填) | 待处理的输入纹理,泛光效果叠加在该图像上。 |
| Intensity(Single) | 整体强度。注意:小于 1 的数值几乎不可察觉,实际调参通常需要显著大于 1 的取值。 |
| ColorWeights(Vector4) | 用于计算初始亮度的颜色权重(见 2.1 节)。可用来把泛光效果限制在特定颜色上。默认值为 NTSC 颜色感知权重;降低 Alpha 分量会把颜色混合为灰度。 |
| Threshold(Single) | 将泛光限制在更亮的区域,低于阈值的像素不参与发光。 |
| GlowGradient(Gradient) | 用于为泛光着色或塑形。它会被乘到每一层模糊核上,梯度越靠右(值越大)对应的层越模糊。调参提示:按住 CTRL 拖动亮度滑块可将亮度调到 1 以上,借此放大某些层(例如放大核心层)来塑造更强烈的效果。 |
| GainAndBias(Vector2) | 用于塑造各模糊层(blur kernel)的分布形态。曲线偏低时效果聚焦于核心(core),曲线偏高时效果偏向模糊部分。很多取值会产生伪影,但用得克制时非常适合打磨特定观感。 |
| MaxLevels(Int32) | 模糊层(level)的数量。最大为 12(对大多数分辨率已经足够)。绝大多数场景无需调整,但在极端场景下,降低它可以优化性能或塑造特殊观感。 |
| Blur(Single) | 偏移模糊量,可用来打磨观感(例如限制泛光的扩散范围)。注意它会造成明显伪影,需要谨慎使用。 |
| Clamp(Boolean) | 在混合前对模糊核进行钳制,会带来略微不同的观感。注意:它不会钳制最终合成结果,最终结果的色调映射需要交给 [ToneMap] 类算子处理。 |
3.1 各参数与着色器/级联的对应关系小结
Intensity、ColorWeights、Threshold→ 直接作用于Bloom-BrightpassPS.hlsl(亮度计算、阈值过滤)与最终合成强度;MaxLevels→ 决定级联的模糊层数量,直接决定需要执行多少次降采样/模糊/上采样,是性能与观感的权衡点;GlowGradient、GainAndBias→ 决定每层模糊核在合成时的权重分布,是"塑形"泛光观感的核心工具;Blur→ 偏移每一层的模糊程度,属于"打破默认曲线"的进阶微调项,容易引发伪影;Clamp→ 在层间合成前做一次钳制,属于观感切换开关,而非输出保护。
四、输出
| 名称 | 类型 |
|---|---|
| Result | T3.Core.DataTypes.Texture2D |
在 Bloom.cs 中,输出槽定义为:
[Output(Guid = "f3fa372d-f037-48fd-8a8d-a0135b4c20cb")] public readonly Slot<T3.Core.DataTypes.Texture2D> Result = new Slot<T3.Core.DataTypes.Texture2D>();即输出仍为一张 Texture2D,可直接接入后续的后期处理算子或混合节点。
五、实战调参建议
官方文档给出的操作要点整理如下:
- 先拉 Intensity:从明显大于 1 的强度起步(1 以下几乎看不出效果),再逐步回落到合适水平;
- 用 Threshold 收窄发光区域:只让高光参与泛光,避免暗部被污染;
- 用 GlowGradient 着色与塑形:将 Gradient 理解为"从左(锐利核心)到右(弥散光晕)的权重曲线",需要放大某级层时按住CTRL拖动亮度滑块突破 1.0;
- 用 GainAndBias 微调分布:以"克制"为原则小幅调整,防止伪影失控;
- MaxLevels 保持默认即可:仅在需要优化性能或刻意收窄泛光扩散时才下调(上限 12);
- Clamp 是个观感开关:开启后模糊核在合并前被钳制,观感略不同,但不要指望它保护最终结果——高光溢出的保护请交给 [ToneMap] 类算子;
- Blur 慎用:它偏移模糊量、可限制泛光扩散,但代价是明显伪影。
5.1 PostFX 管线中的定位
官方文档特别给出了 PostFX 后期管线中的常用组合:
Useful Ops for a PostFX Pipeline: MotionBlur, DepthOfField, ChromaticAbberation, Bloom, Glow, Grain, Blur
即 Bloom 通常与 MotionBlur、DepthOfField、ChromaticAbberation、Glow、Grain、Blur 等算子串联,构成一条完整的电影感后期链。典型的串接思路是:Bloom 负责高光辉光 → Glow 负责整体柔光 → 末端接 Grain 与色调映射。Glow 与 Bloom 可以并存:Bloom 提供高效的高光泛光,Glow 提供更柔和、更低频的整体光晕,二者叠加可营造层次更丰富的发光效果。
六、源码阅读路线
如果想深入理解 Bloom 的实现细节,可按以下路径阅读仓库源码:
- 算子定义(输入输出槽与 GUID):Operators/Lib/Symbols/image/fx/blur/Bloom.cs
- 级联着色器(算法核心):Operators/Lib/Assets/shaders/img/blur/Bloom-BrightpassPS.hlsl、Bloom-DownsamplePS.hlsl、
Bloom-SeparableBlurPS.hlsl、Bloom-UpsamplePS.hlsl - 同目录相关算子:目录索引见 .help/docs/operators/lib/image/fx/blur/README.md,含 Blur、DirectionalBlur、FastBlur、Sharpen 等;
- 同族对比算子:Glow 文档(位于
Lib.image.fx.stylize算子库)。
仓库还自带了大量.t3/.t3ui示例工程(位于Operators/Lib/Symbols/下),官方文档也提示"Please also try the presets"——优先在编辑器中加载预设并逐个调整参数,是理解每个旋钮作用的最快方式。
【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考