TiXL t3 中的 Switch 算子:切换连接的场景图、Command 语义与失效优化详解
TiXL t3 中的 Switch 算子切换连接的场景图、Command 语义与失效优化详解【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3Switch 是 TiXLt3 实时动态图形工具中Lib.flow命名空间下的一个流程类算子用于在多个已连接的子图scene graph之间进行剪辑式硬切换常被用来在不同的场景之间切镜。读完本文你将掌握 Switch 的全部输入参数与输出、Index 的环绕wrap规则、-1 全关 / -2 全开的特殊取值语义以及OptimizeInvalidation这一实验性性能开关在源码层面如何把失效invalidation范围收缩到当前激活的输入子图。1. Switch 在 Lib.flow 中的定位Switch 与Execute、Loop、Once、TimeClip等算子同属Lib.flow流程类算子库见 Lib.flow 索引。该索引对它的官方描述是Switches between connected graphs. Can be used to cut between scenes.也就是说它把若干条 Command 连接当作一组通道通过一个整数 Index 决定当前这一帧实际执行其中哪一条或全部/无。由于它是硬切换而不是渐变混合它适合做镜头切镜、状态机式的场景切换如果需要对场景做透明度渐变混合应使用同库中的BlendScenes算子如果想要一个可视化的时间线方式则应使用TimeClip见 TimeClip 文档。2. 输入参数完整说明原始文档给出的输入参数表如下其中 Commands 为多输入槽Index 与 OptimizeInvalidation 为单值输入槽Name (Relevancy Type)DescriptionCommands(Command Required)Scene InputIndex(Int32)Selects which connection is active starting from 0. -1 deactivates all incoming scenes. -2 activates all incoming scenes. Note that the index is wrapped: If you have two inputs connected, an index of 2 will route to the first.OptimizeInvalidation(Boolean)If enabled, Tool will only invalidate the active connection. This can significantly improve performance for very complex scenes with thousands of Ops. This feature is experimental and might have unexpected side effects.结合算子的项目定义文件 Switch.t3可以补充出文档中未列明的默认值Commands多输入槽MultiInputSlotCommand默认无连接。这是场景输入端口可以连接任意数量的子图 Command 输出连接顺序即通道编号0 起。IndexInt32单输入默认值为 0即默认只执行第一条连接的子图。OptimizeInvalidationBoolean单输入默认值为 false即默认对全部已连接子图做失效传播。3. Index 的取值语义环绕、-1 与 -2文档原文给出的三条核心规则Index 从 0 开始对应第一条连接Index -1时关闭全部连接什么都不执行Index -2时开启全部连接超出连接数量的取值会环绕wrap例如只连接了 2 个输入时Index 2 会路由到第 0 号输入。实现位于 Switch 源码关键分支如下// Operators/Lib/Symbols/flow/Switch.cs节选 if (commands.Count 0 || index -1) { Count.Value 0; return; // -1不执行任何连接 // ... index -2 时遍历所有输入并逐一执行Do all else { index % commands.Count; // 环绕先取模 if (index 0) { index commands.Count; // 负数归一到 [0, count) } _activeIndices.Add(index); commands[index].GetValue(context); commands[index].Value?.RestoreAction?.Invoke(context); }从源码可以进一步确认两个细节环绕实现是index % commands.Count后对负结果加回commands.Count因此除了 -1、-2 两个保留值外任意负数 Index 同样会被环绕到合法范围例如 5 个连接时 Index -3 等效于 2当没有任何连接commands.Count 0时算子直接把 Count 置 0 并返回不执行任何命令。4. 输出Output 与 Count文档定义的输出表NameTypeOutputT3.Core.DataTypes.CommandCountSystem.Int32OutputCommand类型输出下游用它继续串联图形上下文操作例如接Execute等算子CountInt32输出等于当前实际连接并收集到的输入子图数量。源码中UpdateCount通过Commands.GetCollectedTypedInputs().Count计算该值见 Switch.cs多输入槽的收集逻辑在 MultiInputSlot 中实现且嵌套的多输入槽会被展开flattened后一起计入。Count 的实际用途是让下游逻辑知道一共有几路可切例如用它来驱动 UI 或做 Index 的自动环绕。5. 为什么叫 Switch 而不叫 PickCommand 类型的特殊性原文档专门解释了一个容易困惑的命名问题Switch 没有遵循 Pick 系列算子如 PickColor、PickImage 等选择值类算子的命名惯例原因是它还能选择什么都不执行或者全部执行。而根源在于Command 是整个类型系统中唯一不返回数据、只负责执行所连接命令的类型// Core/DataTypes/Command.cs public class Command { public ActionEvaluationContext PrepareAction { get; init; } public ActionEvaluationContext RestoreAction { get; set; } }可以看到Command 本质上是一对执行/恢复回调没有可挑选的数值载荷。对 Pick 类算子来说选择无意味着无值可返回语义不成立而对 Switch 来说不执行任何一条连接是完全合理的状态因此需要独立的 -1 取值。这也解释了它的执行模型是执行 恢复两阶段GetValue(context)触发所选子图的执行随后显式调用RestoreAction见 Switch.cs与Execute算子执行绘制序列后恢复图形上下文的行为一脉相承。6. OptimizeInvalidation把失效传播收缩到激活分支这是文档标注为实验性的关键性能开关。TiXL 是节点图实时渲染引擎每帧需要决定哪些算子变脏dirty需要重新求值——这个过程称为失效传播。在包含成千上万个算子的复杂场景中对全部已连接子图做失效传播本身会成为瓶颈。开启OptimizeInvalidation后Switch 会把自己当前激活的通道编号写入多输入槽上的限制列表// Operators/Lib/Symbols/flow/Switch.cs节选 if (OptimizeInvalidation.GetValue(context)) { var count _activeIndices.Count; if (commandSlot.LimitMultiInputInvalidationToIndices.Length count) { var switchList commandSlot.LimitMultiInputInvalidationToIndices; for (int i 0; i count; i) { switchList[i] _activeIndices[i]; } } else { commandSlot.LimitMultiInputInvalidationToIndices _activeIndices.ToArray(); } }这段数据被 MultiInputSlot.InvalidationOverride 消费当LimitMultiInputInvalidationToIndices.Length 0时只对列表中的下标对应的子图调用InvalidateGraph()其余未激活分支完全不参与失效计算// Core/Operator/Slots/MultiInputSlot.cs节选 // NOTE: In situations with extremely large graphs (1000s of instances) // invalidation can become a bottle neck. In these cases it might be justified // to limit the invalidation to active parts of the subgraph. The [Switch] // operator defines this list. if (multiInputLimitCount 0) { for (int i 0; i multiInputLimitCount; i) { var index LimitMultiInputInvalidationToIndices[i]; if (index collectedCount) continue; target collectedInputs[index].InvalidateGraph(); } } else if (collectedCount 0) { /* ... */ } else { for (int i 0; i collectedCount; i) target collectedInputs[i].InvalidateGraph(); }源码注释明确指出这是专门针对数千个实例的超大图中失效传播成为瓶颈的场景设计的而这个激活列表正是由 Switch 算子定义的。因此该开关的适用画像非常清晰适合开启连接了多个体积很大几千个算子量级的场景子图且任意时刻只激活其中一到两个分支注意事项文档将其标注为实验特性experimental可能产生意外副作用且未激活分支不会被失效传播触及如果这些分支内部依赖外部时间或状态推进其行为可能不符合预期。7. 实战要点小结用 Switch 做硬切把每个镜头/状态作为一个 Command 子图接到 Commands 多输入槽用外部信号按钮、命令序列、MIDI/OSC 输入等驱动 Index记住三个特殊语义0起环绕-1全关-2全开负数除保留值外会环绕而非报错用Count输出校验当前实际接入的分支数避免 Index 与分支数不同步超大场景中按需开启OptimizeInvalidation并注意其实验性定位需要时间线可视化剪辑类似视频编辑软件的时间条时改用 TimeClip需要场景间渐变时用BlendScenes。参考文件本文主体文档Switch 算子文档算子实现Switch.cs算子默认值定义Switch.t3多输入槽与失效优化MultiInputSlot.csCommand 类型定义Command.cs所属算子库索引Lib.flow README可视化替代方案TimeClip.md【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →