news 2026/9/20 3:19:41

TiXL 图像分析算子 WaveForm 完全指南:波形示波器与矢量示波器叠加可视化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TiXL 图像分析算子 WaveForm 完全指南:波形示波器与矢量示波器叠加可视化
  • 音视频
  • 图形学
  • 桌面应用

【免费下载链接】t3

TiXL is an open source software to create realtime motion graphics.

项目地址:https://gitcode.com/GitHub_Trending/t3/t3
点击查看免费下载

WaveForm 是 TiXL(Lib.image.analyze 库)中用于可视化图像颜色与亮度分布的分析算子,它在一张画面上同时叠加 Waveform(亮度波形)与 Vectorscope(矢量色域示波器)两种专业监视工具,被广泛用于色彩校正、调色检查与实时影像监看。读完本文,你将掌握 WaveForm 的全部输入参数与默认值、它背后的 HLSL 计算着色器实现原理,以及如何把它接入 TiXL 节点图做实时视频分析。

算子定位与适用场景

WaveForm 属于 TiXL 的算子库 Lib.image.analyze,该库汇总了图像分析类算子,其中与 WaveForm 直接相关的同类工具有:

  • ImageLevels:同样用于可视化图像亮度分布(直方图式);
  • CompareImages:通过可移动分界线对比处理前后的两张图像;
  • GetImageBrightness:把二维输入的亮度直接输出为 float 值。

WaveForm 的独特之处在于:它不是把亮度信息导出成数值,而是把亮度波形矢量色域示波器以叠加层的形式直接渲染到图像上,让你在实时画面中同时观察"亮度分布是否合理"与"色相/饱和度是否偏移"。正如原文档所说,这类叠加层在色彩校正中有极高的实用价值,国内外大量调色教程都依赖这类示波器判断画面问题。

在实际项目中,WaveForm 常与颜色处理算子(如 ColorGrade)配合使用:先用 ColorGrade 调整色彩,再用 WaveForm 监看调整结果是否过曝、欠曝或偏色。在示例工程 HowToUseColors.t3(如何用色的教学示例)中,WaveForm 被直接实例化并开启了矢量示波器(ShowVectorscope: true),说明它在 TiXL 官方示例中就是作为颜色教学与监看工具出现的。

输入参数详解(含源码默认值)

原文档给出了算子的全部输入参数,本节结合 WaveForm.t3 中实际保存的DefaultValue,补充每个参数的默认值与取值范围说明,方便直接照着调参:

参数名(相关性 & 类型)说明默认值(来自 WaveForm.t3)
EffectTexture(Texture2D)待分析的输入图像(纹理),可直接连接任意图像/视频输出空(需手动连接)
Height(Single)波形显示区域的高度比例,决定亮度波形在画面中的纵向占位0.5
Opacity(Single)波形与矢量示波器叠加层的整体不透明度(0~1),越低越接近"半透明监看"0.14
DimBackground(Single)背景压暗强度,数值越高,原画面越暗,示波器叠加层越突出0.5
ColorIntensity(Single)波形中红/绿/蓝三通道分量的着色强度,值越大颜色越浓0.15
ShowVectorscope(Boolean)是否显示矢量示波器(色域圆环)叠加层false
EnlargeVectorScopeCenter(Single)放大矢量示波器中心区域的显示强度,便于观察低饱和度/暗部区域的色相分布0.5
OverrideSize(Int2)覆盖内部渲染缓冲的尺寸;默认(-1, 0)表示自动使用输入纹理尺寸X: -1, Y: 0
VectorScopePosition(Vector2)矢量示波器叠加层在画面中的位置(归一化坐标)X: 1.17, Y: 0.113

对应的 C# 实现位于 WaveForm.cs,每个输入都通过InputSlot<T>声明并带有固定的 Guid,类型与上表一一对应(如HeightInputSlot<float>ShowVectorscopeInputSlot<bool>OverrideSizeInputSlot<Int2>VectorScopePositionInputSlot<System.Numerics.Vector2>)。从源码可以看出,这些参数会被内部节点图收集后统一写入计算着色器的常量缓冲区(cbufferParamConstants),下一节将详细说明它们如何影响渲染。

输出参数

名称类型
ImgOutputT3.Core.DataTypes.Texture2D

ImgOutput是在 WaveForm.cs 中声明的Slot<Texture2D>输出,携带叠加层后的最终纹理。从 WaveForm.t3 的连接关系看,ImgOutput直接连接自内部RenderTarget8e078c2f节点)的输出,即"背景压暗 → 波形 / 示波器叠加 → 输出"的最终合成结果。

内部实现原理:从节点图到 HLSL

WaveForm 不是一个"魔法黑盒",而是一个用 TiXL 节点图组装出来的复合算子。从 WaveForm.t3 的Children列表可以清晰还原它的内部工作流:

亮度波形(Waveform)的生成链路

  1. 纹理读取与格式准备SrvFromTexture2d026eb5b0)把输入纹理包装成 SRV,SamplerState042a96e3)使用 Wrap 寻址模式;内部Texture2dc2a6f2da)声明了一块R16G16B16A16_Float256×256、绑定ShaderResource | RenderTarget | UnorderedAccess的中间缓冲;
  2. 计算着色器统计ComputeShaderb105eba2)加载着色器源Lib:shaders/img/analyze/waveform-cs.hlsl,由ComputeShaderStage7cb6fbd3)以128×128×1的 Dispatch 规模执行;UavFromTexture2d5d07eac9)把中间缓冲作为 UAV 传入;
  3. 画线绘制ListToBufferDrawLines064843a8等)把统计结果以线条形式绘制出来,线条颜色为白色(W: 0.016)或深色(W: 0.36),形成波形网格。

矢量示波器(Vectorscope)的生成链路

  1. 色域参考图LoadImagee8208f66)加载Lib:shaders/img/analyze/vectorscope.png(仓库中确实存在该 512×512 参考图,见 Operators/Lib/Assets/shaders/img/analyze);
  2. 色点采样ComputeShaderf5a958a0)加载Lib:shaders/img/analyze/sample-vectorscope-points-cs.hlsl,配合RadialPoints(生成圆环点列)与RadialGradient80e08043,内建 5 档黑白渐变)生成色点分布;
  3. 叠加合成Layer2dc3762894,Scale 0.6)与DrawBillboardsc576188d,Scale 0.88)把示波器圆环与色点合成到画面,Transforme3d3fcf4)以VectorScopePosition(默认 X: 1.17, Y: 0.113)控制其位置。

所有内部图层最终汇入Layer2d/DrawScreenQuad等合成节点,输出到RenderTarget,再由Camera8721aec0,AspectRatio 默认 -1)投影后经ImgOutput输出。值得注意的是节点图中还保留了_GridPoints_Oldd9e03f8a)这样的旧版网格生成节点,从命名可以推断波形绘制经历了从"网格点列"到"径向点/画线"的演进。

核心着色器源码逐段剖析

波形统计的核心逻辑集中在 waveform-cs.hlsl,完整源码如下:

cbuffer ParamConstants : register(b0) { float Height; float Opacity; float ClearBackground; float Intensity; } sampler texSampler : register(s0); Texture2D<float4> InputTexture : register(t0); RWTexture2D<float4> WriteOutput : register(u0); groupshared float4 SharedColors[512]; static const float ToRad = 3.141592/180; [numthreads(1,512,1)] void main(uint3 i : SV_DispatchThreadID) { int texWidth; int texHeight; WriteOutput.GetDimensions(texWidth, texHeight); SharedColors[i.y] = i.y > 256 ? float4(0,0,0, ClearBackground) : 0; GroupMemoryBarrierWithGroupSync(); const int steps = 256; if(i.y == 0) { float dashColor = i.x % 8 < 4 ? 1 : 0; SharedColors[511] = float4(dashColor.xxx, 1); SharedColors[256] = float4(dashColor.xxx, 1); [fastopt] for(int rowIndex= 0; rowIndex < 256; rowIndex++) { float2 uv = float2(float2( i.x / (float)texWidth, (float) rowIndex / 256.0 )); float4 col = InputTexture.SampleLevel(texSampler, uv,0); int3 level = 512 - clamp( col.rgb * 256, 0, 511); SharedColors[level.r] += float4(Intensity,0,0,Opacity) * col.a; SharedColors[level.g] += float4(0,Intensity,0,Opacity) * col.a; SharedColors[level.b] += float4(0,0,Intensity,Opacity) * col.a; } } GroupMemoryBarrierWithGroupSync(); WriteOutput[i.xy] = clamp(SharedColors[i.y], 0, 1); }

逐段解读其原理:

  • 常量缓冲区HeightOpacityClearBackgroundIntensity四个 uniform 与算子的HeightOpacityDimBackgroundColorIntensity四个输入一一对应,节点图负责把这些参数打包进 cbuffer;
  • 线程组织[numthreads(1,512,1)]表示每个线程组有 512 个线程,对应SharedColors[512]这个共享内存数组——它把亮度级(0~255 共 256 级亮度 bin,另加波形刻度区)映射到共享内存槽位,实现 GPU 内高效直方图累加;
  • 采样与直方图累加:线程组第一行(i.y == 0)的线程逐行遍历输入图像(rowIndex0~255,配合i.x / texWidth归一化 UV),对每个像素做col.rgb * 256得到亮度等级,再以512 - clamp(...)反向映射到共享内存下标,把(Intensity, 0, 0, Opacity)(0, Intensity, 0, Opacity)(0, 0, Intensity, Opacity)分别累加到 R/G/B 三个亮度槽——这正是波形上红、绿、蓝三条彩色曲线的来源,累加强度受ColorIntensity(即Intensity)控制;
  • 波形刻度线i.x % 8 < 4生成 4:4 交替的虚线样式,写入SharedColors[511](顶部)与SharedColors[256](中位线),形成示波器上的参考刻度;
  • 同步与输出:两次GroupMemoryBarrierWithGroupSync()确保共享内存读写同步,最终WriteOutput[i.xy] = clamp(SharedColors[i.y], 0, 1)把直方图写回纹理。

SharedColors[i.y] = i.y > 256 ? float4(0,0,0, ClearBackground) : 0;可以看出,输出纹理上半部分(256 槽以上)会被ClearBackground(即DimBackground输入)填充为半透明黑色,用于压暗背景、突出波形——这与参数的命名语义完全吻合。

典型使用步骤

在 TiXL 中接入 WaveForm 的完整流程如下:

  1. 从算子库Lib.image.analyze拖入WaveForm节点到你的图像处理链末端;
  2. 把任意图像/视频/渲染结果(如EffectTexture输入)连接到EffectTexture端口;
  3. 按需调整参数:
    • Height(默认 0.5)控制波形纵向占位;
    • Opacity(默认 0.14)控制叠加层的半透明程度,监看时建议保持低值以免遮挡画面;
    • DimBackground(默认 0.5)压暗背景,让示波器更醒目;
    • ColorIntensity(默认 0.15)控制 RGB 三通道波形的着色浓度;
  4. 打开ShowVectorscope(默认 false)显示色域圆环,配合EnlargeVectorScopeCenter(默认 0.5)放大中心区域观察暗部色相,用VectorScopePosition(默认 X: 1.17, Y: 0.113)把示波器摆到画面合适位置;
  5. ImgOutput连接到最终合成或输出节点,即可在实时画面中监看亮度波形与色域分布。

参考示例:HowToUseColors.t3 中同时实例化了两个 WaveForm(一个开启ShowVectorscope: true)与 ImageLevels,展示了在调色教学场景下的典型摆放方式。

实用调参建议

基于源码中的默认值与着色器逻辑,可以给出以下实测导向的建议:

  • 监看亮度是否过曝/欠曝:观察波形顶部的白色刻度线(SharedColors[511])。若波形大量贴顶被削平,说明高光溢出;若整体集中在底部,说明画面偏暗。中位刻度(SharedColors[256])对应 50% 灰,可用于判断中间调位置;
  • 判断偏色:波形中红、绿、蓝三条曲线重叠度越高,画面越接近中性。某条曲线明显高于其他两条,说明该色通道过量;ColorIntensity提高后三条曲线的颜色区分会更明显;
  • 检查饱和度与色相:打开ShowVectorscope后,参考圆环(来自vectorscope.pngRadialPoints生成的圆环)用于对照色相角度;色点聚集在圆心附近表示低饱和度,向外扩散表示高饱和;中心区域被EnlargeVectorScopeCenter放大后,低饱和度区域的细微色相偏移更容易被观察到;
  • 实时性能:波形统计使用共享内存直方图,每线程组仅 512 线程即可完成 256 级亮度统计,OverrideSize默认(-1, 0)自动跟随输入尺寸,通常无需手动指定缓冲大小。

相关资源索引

  • 算子文档:WaveForm.md、Lib.image.analyze 目录
  • C# 实现:WaveForm.cs
  • 节点图定义(含全部默认值与连接关系):WaveForm.t3
  • 核心着色器:waveform-cs.hlsl、sample-vectorscope-points-cs.hlsl
  • 色域参考图:vectorscope.png
  • 使用示例:HowToUseColors.t3

延伸阅读:与 WaveForm 同属图像分析家族、常搭配使用的算子还有 ImageLevels(亮度分布直方图)、CompareImages(前后对比)、GetImageBrightness(亮度数值化输出),以及 ColorGrade(色彩分级)——把它们组合起来,即可构建一套完整的"调色 → 监看 → 校验"工作流。

  • 音视频
  • 图形学
  • 桌面应用

【免费下载链接】t3

TiXL is an open source software to create realtime motion graphics.

项目地址:https://gitcode.com/GitHub_Trending/t3/t3
点击查看免费下载

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 3:17:23

MBA写作降AI率实测:8类工具原理、效果与避坑指南

MBA课程作业最让人头疼的事之一&#xff0c;就是案例分析报告写完之后&#xff0c;打开学校系统里的AI检测一跑&#xff0c;显示“疑似AI生成比例&#xff1a;42%”。更离谱的是&#xff0c;有些段落明明是自己一个字一个字敲的&#xff0c;也被标红。于是大家开始到处找所谓的…

作者头像 李华
网站建设 2026/9/20 3:16:50

RapidOCR 在 Python 3.12 装不上?2 步绕开依赖冲突

RapidOCR 在 Python 3.12 装不上&#xff1f;2 步绕开依赖冲突 【免费下载链接】RapidOCR &#x1f4c4; Awesome OCR multiple programing languages toolkits based on ONNX Runtime, OpenVINO, MNN, PaddlePaddle, TensorRT and PyTorch. 项目地址: https://gitcode.com/G…

作者头像 李华
网站建设 2026/9/20 3:15:20

Bandizip 免费版实测:从下载安装到高效压缩配置全指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 3:13:22

PCIe连接器自动组装检测设备选型实战:从CEM到M.2全解析

做连接器自动化组装这几年来&#xff0c;我前前后后经手过不少PCIe相关的项目&#xff0c;从主板上的CEM插槽到服务器里的Mini PCIe、M.2网卡座&#xff0c;再到高速背板用的SlimSAS&#xff0c;每一类看着都是“插一个连接器”&#xff0c;实际上设备方案差别很大。每次项目启…

作者头像 李华
网站建设 2026/9/20 3:09:06

Karukan KV cache管理全解析:llama.cpp序列上限与Beam的工程边界

Karukan KV cache管理全解析&#xff1a;llama.cpp序列上限与Beam的工程边界 【免费下载链接】karukan Japanese Input Method System for Linux, macOS, Neural Kana-Kanji Conversion Engine 项目地址: https://gitcode.com/GitHub_Trending/ka/karukan Karukan 是一款…

作者头像 李华