- 音视频
- 图形学
- 桌面应用
【免费下载链接】t3
TiXL is an open source software to create realtime motion graphics.
TiXL(t3)作为一款实时动态图形创作工具,其算子库Lib.numbers.color提供了从不同色彩模型(HSL、HSB、OKLCh)构造颜色的能力。本文围绕 HSLToColor 算子文档,完整讲解其输入参数语义、输出格式、底层转换算法以及与 HSBToColor 的差异,并结合仓库源码与示例工程给出可直接落地的调色实战方案。读完本文,你将能熟练使用该算子实现程序化配色、色相循环动画等常见需求。
算子概述与所属模块
HSLToColor 是 TiXL 算子库Lib.numbers.color分类下的一个基础算子,功能如其名:根据 HSL(色相、饱和度、明度)设置生成一个 RGBA 颜色。它不依赖任何纹理或外部输入,只做纯数值到颜色的转换,因此非常适合作为颜色系统的"源头"节点,接入后续的颜色混合、渐变构建、材质参数等下游算子。
在 TiXL 的算子浏览器中,它位于Lib → numbers → color → HSLToColor,与之同组的算子在 Lib.numbers.color 模块文档 中可以看到完整列表,包括 HSBToColor、BlendColors、BuildGradient、SampleGradient等。该模块文档的末尾标注了Auto-generated from the operator library,即这些算子文档由算子库自动生成,其中 HSLToColor 的条目描述为:
Creates an RGBA color from HSL settings
输入参数详解
原文档给出了四个输入参数,均为Single(即float)类型。结合仓库中的符号定义文件 HSLToColor.t3(保存各输入的默认值)与 HSLToColor.t3ui(保存 UI 滑杆范围与钳制标志),可以得到下表所示的完整参数语义:
| 参数名 | 类型 | 说明 | 默认值 | UI 范围 | 钳制 |
|---|---|---|---|---|---|
| Hue | Single | 归一化色相,0..1 即完整一圈色环(源码中会乘以 360 换算为角度) | 0.0 | 0..1 | 无钳制 |
| Saturation | Single | 饱和度(0 为灰色,1 为纯色) | 0.0 | 0..1 | ClampMin + ClampMax |
| Lightness | Single | 明度(0 为黑,0.5 为最纯色,1 为白) | 0.50000006 | 0..1(步进 0.01) | 仅 ClampMin |
| Alpha | Single | 不透明度(0 为全透明,1 为不透明) | 1.0 | 0..1 | ClampMin + ClampMax |
几个值得注意的细节:
- Hue 采用归一化 0..1 表示法,这一点与 HSBToColor 直接使用角度(0..360)不同。源码中
var hue = (Hue.GetValue(context) % 1) * 360f;会先对输入取模 1,再放大到 0..360 度。因此输入 0.25 对应 90°(黄绿色区域)、0.5 对应 180°(青色区域)、0.75 对应 270°(紫色区域)。 - Saturation 与 Alpha 在 UI 上做了双向钳制(
ClampMin: true, ClampMax: true),而Hue 不钳制、Lightness 只钳制下限,说明 Hue 的取值意图是允许通过连接外部信号(如动画、LFO)越过 0..1 边界并借助取模实现自动回绕。 - Lightness 的默认值是 0.50000006(近似 0.5),配合默认的 Hue=0、Saturation=0,HSLToColor 的初始输出是接近中灰的颜色,而不是白色或黑色,这与常见"颜色节点默认白色"的习惯不同,首次接入时需要留意。
输出解析:Vector4
算子的唯一输出Color类型为System.Numerics.Vector4,四个分量依次对应R、G、B、A,每个分量取值范围为 0..1(浮点,而非 0..255 的字节值)。在 TiXL 中,Vector4是颜色在节点图上流通的标准载体:
- 源码中输出槽位定义为
public readonly Slot<Vector4> Color = new();,GUID 为A73DC8D3-ECC5-454A-999A-1C79442FF2E2(见 HSLToColor.cs)。 - 它可以直接接入接受颜色的算子输入,也可以配合
RgbaToColor之类的包装算子转换为 TiXL 内部的 Color 结构体(该结构体基于Vector4 Rgba字段封装了 RGBA 访问器、HSV 互转、混合模式、ToHTML()等丰富方法),再送入需要Color类型参数的下游算子。 - 输出在每次求值时通过
Color.UpdateAction += Update;注册的更新回调计算,Update(EvaluationContext context)中读取四个输入槽位的当前值并写入Color.Value = new Vector4(fR, fG, fB, Alpha.GetValue(context));,因此它是一个无状态、每帧实时求值的算子,天然适合被动画信号驱动。
源码级实现原理:三步式 HSL→RGB 转换
HSLToColor.cs 中的Update方法实现了一套精简的 HSL 到 RGB 转换,逻辑可以概括为三步:
第一步:把色相映射到三个 120° 扇区并生成每个通道的饱和度权重。
var hue = (Hue.GetValue(context) % 1) * 360f; // 归一化色相 → 角度 // 0..120°:红→绿过渡 fSatR = (120.0f - hue) / 60.0f; fSatG = hue / 60.0f; fSatB = 0.0f; // 120..240°:绿→蓝过渡 fSatR = 0.0f; fSatG = (240.0f - hue) / 60.0f; fSatB = (hue - 120.0f) / 60.0f; // 240..360°:蓝→红过渡 fSatR = (hue - 240.0f) / 60.0f; fSatG = 0.0f; fSatB = (360.0f - hue) / 60.0f; // 每个通道权重钳制到 [0, 1] fSatR = (fSatR < 1.0f) ? fSatR : 1.0f; // 对 fSatG、fSatB 同理可以看到每个扇区内相邻两个通道各以 60° 为斜坡线性升降,第三个通道为 0,这构成了色相环上红→黄→绿→青→蓝→品红的六段过渡骨架。
第二步:将饱和度混合进通道权重。
var fTmpR = 2.0f * sat * fSatR + (1.0f - sat);当sat = 0时,fTmp = 1,三个通道权重相等,输出退化为灰色;当sat = 1时,fTmp = 2 * fSat,通道权重完全由色相扇区决定,输出为全饱和色。
第三步:根据明度拆分两段映射。
if (brightness < 0.5f) { fR = brightness * fTmpR; // 暗部:直接缩放 } else { fR = (1.0f - brightness) * fTmpR + 2.0f * brightness - 1.0f; // 亮部:向白色过渡 }- 当
Lightness = 0时输出纯黑; - 当
Lightness = 0.5、Saturation = 1时输出对应色相的最纯颜色(这也是 UI 默认明度取 0.5 的原因); - 当
Lightness = 1时输出纯白; - 在
Saturation = 0的灰色轴上,该公式恰好退化为R = G = B = Lightness,从黑经中灰到白的渐变是平滑连续的。
顺带一提,Color.cs 中还提供了另一个更接近标准 HSL 定义的静态方法Color.ColorFromHsl(h, s, l, a)(基于c = (1 - |2l - 1|) * s的圆柱坐标公式),而 HSLToColor 算子采用的是上述简化近似算法。两者在多数常见取值下结果接近,但在中间明度、低饱和区域会有细微差异;如果追求严格的色彩学一致性,可对照使用。
与 HSBToColor 的差异:选哪个?
Lib.numbers.color 模块文档 同时收录了 HSLToColor 与 HSBToColor,后者文档明确写着 "same as HSB in the Color Picker",即与 TiXL 拾色器中的 HSB 模型一致。二者的关键差异如下:
| 维度 | HSLToColor | HSBToColor |
|---|---|---|
| 第三个分量 | Lightness(明度,0=黑,0.5=最纯,1=白) | Brightness(亮度,0=黑,1=最亮) |
| 色相输入 | 归一化 0..1(自动取模) | 角度 0..360(源码中hue %= 360f并处理负值) |
| 饱和度 0 时 | 灰色渐变轴,明度决定灰阶 | 源码中直接输出灰度r = g = b = brightness |
| 用途 | 适合追求色彩感知均匀、需要控制明暗的配色 | 适合与拾色器 UI 保持一致、直觉式调色 |
选择建议:当你在做基于色相的循环动画(如彩虹扫过)时,HSLToColor 的归一化色相配合取模回绕更省心;当你需要与用户在拾色器中看到的结果完全一致时,使用 HSBToColor 更稳妥。
实战用法:从仓库示例看典型接线
仓库自带的示例工程 HowToUseColors.t3 中实际使用了两处 HSLToColor 实例,可以作为接线参考:
- 第一处(文件第 776 行起)设置了
Hue = 0.01、Saturation = 0.78,即一个低色相偏红、高饱和的暖色; - 第二处(第 859 行起)设置了
Saturation = 0.14,即一个低饱和的浅色调; - 两处输出均通过
RgbaToColor等包装节点继续向下游传递,证明Vector4输出可以被后续颜色算子正常消费。
由此可以总结出几条典型用法:
- 静态配色:直接给 Hue/Saturation/Lightness 键入常数值,输出接
BlendColors、DefineGradient或材质输入,快速搭建统一色板。 - 色相循环动画:将
Loop、AnimValue或任意 LFO 的输出接到 Hue 上。由于 Hue 采用 0..1 归一化并自动取模,0→1 的线性扫描即为完整一圈色相环,且越过 1 后会自动回绕,无需手动取模。 - 明暗节奏:将音频分析(如节拍能量)映射到 Lightness 或 Alpha,让颜色明暗随音乐呼吸,配合 Lib.numbers.color 中的
SampleGradient、GradientsToTexture即可把单一颜色扩展为整条渐变动画。 - 与其他色彩算子混用:HSLToColor 作为"源头"接
BlendColors做双色混合,或接PickColorFromList做调色盘切换,都属于常见组合。
常见问题与注意事项
- Hue 是归一化值,不是角度:传 90 并不会得到 90° 的颜色,而是
90 % 1 = 0得到红色。需要角度时先除以 360。 - Hue 无钳制且取模:源码只做了
% 1,未对负数取正,因此输入-0.25会得到-90°的色相,可能产生与预期不符的扇区计算。建议在接线层保证 Hue 输入不小于 0。 - 输出未显式钳制 RGB:三步算法对中间权重做了钳制,但最终 RGB 没有再次 clamp。在极端取值(如 Lightness > 1 或负值)下可能出现超出 0..1 的颜色分量,接入渲染前建议由下游节点钳制。
- Saturation = 0 时是灰色轴:此时无论 Hue 取何值,输出都是灰阶,这是 HSL 模型的正常行为,不要误以为是 Bug。
- 默认输出不是白色:默认 Lightness ≈ 0.5、Saturation = 0,初始输出为中灰色;如需白色,请将 Lightness 调到 1 或把 Saturation 设为 0 且 Lightness 接近 1。
总结
HSLToColor 是 TiXL 中连接"数值世界"与"颜色世界"的基础桥梁:它以归一化 Hue(0..1 一圈色环)、Saturation、Lightness、Alpha 四个浮点输入,实时输出System.Numerics.Vector4形式的 RGBA 颜色,源码实现采用三扇区线性斜坡加明度两段映射的轻量近似算法(见 HSLToColor.cs),默认值与 UI 范围由 HSLToColor.t3 与 HSLToColor.t3ui 共同定义。理解其归一化色相、0.5 明度基准、无钳制边界等特性后,无论是做静态色板、色相循环动画还是随音乐呼吸的明暗节奏,它都是值得优先选择的第一级颜色节点。
- 音视频
- 图形学
- 桌面应用
【免费下载链接】t3
TiXL is an open source software to create realtime motion graphics.
相关推荐
TiXL Rings 算子完整指南:用参数化 Shader 生成程序化环形纹理
TiXL Rings 算子完整指南:用参数化 Shader 生成程序化环形纹理 Rings 是 TiXL(Lib.image.generate.pattern
音视频图形学桌面应用TiXL NGonMesh 算子实战指南:程序化圆形网格的生成原理、参数详解与渲染管线应用
TiXL NGonMesh 算子实战指南:程序化圆形网格的生成原理、参数详解与渲染管线应用 导读 NGonMesh 是 TiXL 的 Lib.mesh.gene
音视频图形学桌面应用TiXL Raster3dField 算子详解:用 Raymarching 生成程序化栅格 3D 纹理并映射到网格
TiXL Raster3dField 算子详解:用 Raymarching 生成程序化栅格 3D 纹理并映射到网格 TiXL(t3)的 Raster3dFiel
音视频图形学桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考