TiXL DirectionalBlur 运算符详解:方向模糊的参数体系与 GPU 着色器实现原理
2026/9/19 9:39:43 网站建设 项目流程

TiXL DirectionalBlur 运算符详解:方向模糊的参数体系与 GPU 着色器实现原理

【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3

DirectionalBlur 是 TiXL 图像处理库Lib.image.fx.blur中的一个 GPU 模糊运算符,用于沿任意角度方向对传入图像产生运动模糊效果。本文基于其官方文档,结合仓库中的 HLSL 着色器实现、运算符 C# 类 与 运算符定义文件,完整讲解全部 12 个输入参数的语义与默认值、FXTexture 双通道(R/G)控制协议,以及高斯加权对称采样的底层算法,读完即可在 TiXL 中熟练搭建方向模糊与"模糊版输入作为控制纹理"的进阶效果。

功能概述

DirectionalBlur沿一个方向角度模糊传入的图像(Blurs the incoming image along a directional angle),适合模拟摄像机运动、物体高速移动、速度线等动感效果。与同目录下的 Blur(各向同性模糊)不同,它的模糊方向由角度参数显式控制,且支持通过一张额外的"效果纹理"(FXTexture)在画面不同区域动态改写角度与强度。

它的独特能力在于:角度和强度都可以通过一张 FXTexture 逐像素覆盖,纹理的 R 通道代表角度(Angle),G 通道代表强度(Strength)。官方文档特别提示,使用一张"输入图像自身的模糊版本"作为效果纹理尤其有趣(Using an effects texture, especially one that is a blurred version of the input image, is particularly interesting),可以派生出类似边缘发丝光、区域变速模糊等视觉风格。

该运算符归属于 Lib.image.fx.blur 运算符家族,与 Bloom、Blur、FastBlur、Sharpen 并列,是整个库中少数支持"逐像素方向控制"的模糊工具。

输入参数详解

DirectionalBlur 共暴露 12 个输入槽(与 DirectionalBlur.cs 中声明的输入槽一一对应),下表汇总了文档中的参数清单,并补充了从 DirectionalBlur.t3 中提取的默认值与取值范围说明:

名称类型默认值说明
ImageTexture2D(必填)null待模糊的输入图像
SizeSingle0.1模糊位移总长度(以 UV 为单位),值越大拖尾越长
SamplesSingle16.0单侧采样次数,决定拖尾的平滑度与细腻度
AngleSingle0.0基础模糊方向角,单位度(0° 为水平)
FxTexturesTexture2Dnull(未连接)可选控制纹理:R 通道提供角度增量,G 通道提供强度倍率
FxAngleFactorSingle1.0控制纹理 R 通道对角度的缩放系数(0 表示禁用角度覆盖)
FxSizeFactorSingle0.0控制纹理 G 通道对强度的缩放系数(0 表示禁用强度覆盖)
RefinementPassBooleanfalse是否启用细化通道(二次渲染,提升拖尾尾部细节)
RefinementSamplesInt326细化通道的采样次数
RefineSizeFactorSingle0.0细化通道的尺寸因子,可缩小细化通道的模糊位移
WrapTextureAddressModeClamp采样越界时的纹理寻址模式
ResolutionInt2(0, 0)输出分辨率;设为 0 时自动跟随目标分辨率

注:Image是 Required(必填)输入,其余参数均有默认值,直接连接一张纹理即可得到可用的方向模糊输出。

参数的核心作用

  • Size 与 Samples 决定拖尾形态:在着色器中,二者相除得到单次采样步长dir = dir * (strength / NumberOfSamples)。固定 Size 时,Samples 越大,每步位移越小、拖尾越连续平滑,但 GPU 开销线性增长(循环体执行 2×N 次纹理采样)。
  • Angle 决定方向Angle以度为单位传入着色器后转换为弧度,并换算为(cos, sin)方向向量。FXTexture 未连接时(FxAngleFactor 默认 1.0,但 FxTexture 的 r 通道取 0),角度完全由Angle决定。
  • FxAngleFactor / FxSizeFactor 是开关型系数:着色器中角度公式为angle = (Angle + FxAngleFactor * fx.r * 360)。将FxAngleFactor设为 0 即彻底关闭纹理角度覆盖;同理strength = Size * (1 + FxSizeFactor * fx.g)FxSizeFactor = 0时强度覆盖不生效。FxAngleFactor默认即为 1.0,而FxSizeFactor默认 0.0,说明默认只开放角度覆盖。
  • Wrap 控制边缘行为:模糊采样会读取当前位置前后多个像素,当采样点越出纹理边界时,由TextureAddressMode(如 Clamp、Wrap)决定取边还是回绕,直接决定画面边缘处的拖尾是否"漏色"。默认 Clamp 在大多数画面中表现最稳。

输出

名称类型
TextureOutputT3.Core.DataTypes.Texture2D

唯一的输出槽在 DirectionalBlur.cs 中声明,输出与输入同尺寸的模糊结果纹理,可直接连入后续图像处理链或最终合成。

GPU 实现原理:从着色器看方向模糊算法

DirectionalBlur 的核心逻辑全部在单像素着色器 DirectionalBlur.hlsl 中完成,全部代码如下:

cbuffer ParamConstants : register(b0) { float Size; float NumberOfSamples; float Angle; float FxAngleFactor; float FxSizeFactor; } cbuffer Resolution : register(b2) { float TargetWidth; float TargetHeight; }

高斯权重表

static const int WEIGHT_COUNT = 10; static const float Gauss[WEIGHT_COUNT] = { 0.93, 0.86, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1 };

算法并非均匀加权平均,而是使用一张 10 级、从 0.93 递减到 0.1 的静态高斯权重表:越靠近采样起点(当前位置)的样本权重越大,越远处的样本权重越小。这使模糊结果保留中心细节、拖尾呈现平滑衰减,而不是生硬的"重影"。

角度与强度的逐像素计算

float4 fx = FxTexture.Sample(samLinear, uv); float angle = (Angle + FxAngleFactor * fx.r * 360)* 3.141578/180; float2 dir = float2(cos(angle), sin(angle) ); float strength = Size * (1 + FxSizeFactor * fx.g); dir *= strength / NumberOfSamples; dir.y *= aspectRatio;
  • 用当前像素的 UV 采样FxTexture:R 通道经FxAngleFactor放大 360 倍后叠加到Angle上(即 R=1.0 时等效增加整整一圈 360°),再换算为弧度;
  • strengthSizeFxSizeFactor * fx.g共同决定;
  • 单位方向向量乘以strength / NumberOfSamples得到单次采样步长;
  • dir.y *= aspectRatio(宽高比修正)是保证方向角视觉正确性的关键一步:由于 UV 坐标系下像素并非正方形,若不修正 y 分量,斜向模糊会因宽高比失真而偏离设定的角度。这是从源码中可以明确看到的一个重要实现细节。

对称高斯采样循环

float2 pos = dir; float4 c = InputTexture.Sample(samLinear, input.texCoord); float totalWeight = 1; for (int i = 0; i < NumberOfSamples; ++i) { float index = (float)i*(WEIGHT_COUNT - 1)/NumberOfSamples; float weight = lerp(Gauss[(int)index], Gauss[(int)index + 1], frac(index)); c += InputTexture.Sample(samLinear, input.texCoord + pos)*weight; c += InputTexture.Sample(samLinear, input.texCoord - pos)*weight; pos += dir; totalWeight += 2*weight; } c.rgb = c/totalWeight; c.a = clamp(c.a/totalWeight, 0,1); return clamp(c,0,1000);
  • 循环沿方向向量逐级外推采样位置,对+pos-pos双向对称采样(一次循环两次采样),这就是为什么"拖尾"会同时向角度正反两个方向延伸,构成以原像素为中心的直线模糊;
  • 权重通过对高斯表相邻两项做lerp插值获得,使Samples可以与固定长度的权重表(10 级)解耦,任意采样数都能得到平滑的权重曲线;
  • 中心像素权重恒为 1,两侧权重以totalWeight += 2*weight累加,最终 RGB 与 Alpha 都除以总权重完成归一化,保证模糊前后整体亮度一致,最后clamp(c, 0, 1000)防止 HDR 数值溢出。

内部结构:主通道与细化通道

从 DirectionalBlur.t3 的连接图可以推断出该运算符内部由两个_multiImageFxSetup渲染通道组成:一个主模糊通道,一个由RefinementPass控制的细化通道,二者输出通过PickTexture选择。

  • RefinementPass = false(默认):仅执行主通道,使用SizeSamplesAngle等参数直接渲染;
  • RefinementPass = true:启用细化通道,以独立的RefinementSamples(默认 6)与RefineSizeFactor进行二次渲染,用于增强拖尾尾部的细节层次;
  • BoolToInt将布尔开关转为选择值驱动PickTexture,内部还包含DivSize / Samples换算步长)、Multiply(细化尺寸因子缩放)等运算节点,以及一个加载Lib:images/basic/black-pixel.pngLoadImage作为UseFallbackTexture的回退纹理——当 FxTextures 未连接时,用黑色像素纹理保证着色器采样不会读空。

这种"一个运算符 = 一组内部算子图 + 一段 HLSL"的组合模式,是 TiXL 运算符库的通用组织方式:外层的 .t3 图负责参数路由与通道调度,真正的像素运算全部交给 GPU 着色器。

实战建议:把输入图像的模糊版当控制纹理

官方文档特别推荐了 FxTextures 的一种玩法:先对输入图像做一次模糊,再把模糊结果作为 FxTextures 输入。其效果逻辑在源码中清晰可见:

  • 模糊后的纹理天然"抹平"了高频细节,其 R 通道在亮区/暗区之间呈现平滑过渡,作为角度源可以让模糊方向沿图像亮度梯度渐变,形成类似"沿轮廓方向流动"的质感;
  • G 通道携带区域亮度信息,配合FxSizeFactor可以让高亮区域拖尾更长、暗部几乎不动,实现局部变速模糊。

建议的参数起点:Size0.05~0.2,Samples8~32(实时场景取低值),FxAngleFactor1.0,FxSizeFactor0.5~2.0,Wrap保持 Clamp。若追求拖尾更柔和的边缘,可开启RefinementPass并保持RefinementSamples在 4~8 之间,注意细化通道会增加一整个全屏 Pass 的 GPU 开销。

相关资源

  • DirectionalBlur 官方文档(本文关联文档)
  • Lib.image.fx.blur 运算符目录
  • DirectionalBlur.hlsl 着色器源码
  • DirectionalBlur.cs 运算符类
  • DirectionalBlur.t3 运算符定义与默认值
  • 同级对比:非方向性的 Blur 与更快、仅提供半径控制的 FastBlur

【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询