BACK TO ARCHIVE
pipeline td framework houdini usd interoperability dcc mechanics pdg solaris

在 Houdini 中集成 Conduit:从工具碎片到 ProductIO 框架

04.27.2026 ADUCG RESEARCH

原文:https://medium.com/blue-sky-tech-blog/integrating-conduit-in-houdini-5f77c7597bab
相关阅读:(Need a refresher on Conduit? Check out: Conduit: Introduction)

背景:Conduit 很成熟,但 DCC 集成还在路上

作者在 2019 年加入 Blue Sky Studios 时,Conduit 已经是很成熟的一套系统:有稳定的 API、类似 Git 的命令行工具,以及一套明确的数据管理规则。但另一边,“生产工作流”和“DCC 集成”(尤其是 Houdini)仍在不断摸索中。

他最早在 FX 团队里用 Houdini 的早期 Conduit 工具做特效流程,很快就发现这些工具既没有充分利用 Conduit 的能力,也没有发挥 Houdini 的程序化优势。于是他开始着手把这座“桥”重新理一遍。


问题从哪来:不再使用文件路径

Conduit 推动的一次关键变化是:不再直接依赖文件路径,一切都围绕 Product(并且是版本化/可追踪的)来运作。

这带来的直接影响是:在 Houdini 里,任何涉及读写的节点都不得不做一件事——把 Product 转换为真实路径

比如要写一个 USD 文件,你需要:

  1. 选择一个 Product(例如文中提到的 PRI)。
  2. 把它声明为 Workspace 的一个 Output。
  3. 最终 Output 才会携带“实际写入到哪里”的路径。

在流程还简单时,大家可以用“针对某个节点/某个工具”的方式去做适配:包一层 HDA,再包一层 Python 类,用 Conduit API 把路径解析出来。

但随着 Solaris 的出现(直接读取与组合 USD),需要和 Conduit 交互的节点越来越多:每加一类节点就要再包一层;不同部门又各做各的,最后就是工具分裂、维护成本上升。

作者想做的事情很明确:把 Houdini 里“所有和 Conduit 交互的工具”统一到同一套机制上,并且尽量做到格式无关、上下文无关。


第一块:ProductPDG —— 把 Product 管理带进 PDG

在解决 I/O 节点之前,作者先处理一个更基础的问题:很长一段时间里,Product 的操作(checkout、commit、publish 等)要么依赖 API/CLI,要么依赖固定 GUI,艺术家很难按自己的需求做组合和自动化。

作者的切入点是 PDG:既然很多流程天然需要并行、可扩展,为什么不把 Conduit 的 Product 操作也做成 PDG 节点,让 TA 能像搭图一样组织它们?

结果就是 ProductPDG

  • 把 commit / checkout 等 PDG 节点做成 TOP HDA
  • 给出一条核心约定:每个 work item 表示一个 ProductItem,并把 Product 数据序列化到 work item 的 attributes 里
  • 这样 attributes 就可以像普通 PDG 属性一样用于构建依赖图

work item 里能直接查看 Product 数据,利于排查与理解:

这套方式的价值在于:不需要写 Conduit 相关代码,也能搭出较复杂的自动化流程,并且天然具备“上农场”的潜力(作者还提到团队在做自研 PDG Scheduler)。


第二块:ProductIO —— 统一 Houdini 的读写方式

接下来作者把问题收敛到 Conduit 的几个基本事实(这是 ProductIO 的“轴”):

  • 一个 hipfile 对应一个 Workspace
  • hipfile 会从 Input Products 读取数据
  • hipfile 会向 Output Products 写入数据

目标是:在 Houdini 里对任意类型的数据(usd / vdb / bgeo 等),都能用统一方式建立输入输出,并且可同时作用于多个 Products。

作者先把 Input / Output 重新定义得更清晰:

  • Input:带版本信息(读哪个版本)
  • Output:没有版本(通常代表“要生成的结果”,生成后再 commit)
  • 两者底层都继承自同一个 ProductItem(都“绑定到一个 Product”)
Note

这里有一个很重要的观察:以前大家常把 Input/Output 当两套东西写两套实现,但在 Conduit 的抽象里,它们本来就来自同一个对象体系。ProductIO 把这点落实到 Houdini 的实现里,是后面“统一 I/O”能成立的前提。


让节点“Productize”:用 Product Properties 做 Mixin

作者一开始考虑做一个底层节点,让其他节点继承它来获得 Product 能力。但 Houdini 的上下文(SOP/LOP 等)太多,纯继承方案会逼着你为每个 context 再造一套低层节点。

最终他们选择了 Mixin 的思路:让 Productization 变成一个“可加到任意节点上的附加能力”,实现形式就是 Product Properties —— 一组可以加到任何节点上的参数集合,类似 Houdini 自己的 Node Properties。

通过添加 Product Properties:

  • 用户能在节点上看到通用的 Product 参数(例如 PRI 字段 + Product Browser)
  • I/O 连接在背后自动管理
  • 节点会缓存 Input/Output 的实例,减少不必要的服务调用
  • 任何人都可以给自定义 HDA 或内置节点加上这套能力(跨 context)

并且,节点会在 node info 里显示 Product 相关信息,帮助定位依赖:


Output Graph:把“每个节点的输出流程”拼成一张可控的总图

作者强调:Output 往往不仅仅是“写一个文件”,它通常对应一个输出过程——比如写 USD、或者渲染一段序列帧。

ProductIO 给 Output 节点引入了 Output Graph 的概念:

  • 每个 Output 节点可以包含一个自带的 TOP 图(用 Houdini 的 Target TOP Network 参数把 PDG UI 嵌进去)
  • 用户可以单独跑某个节点的输出过程
  • 但更重要的是:能把多个 Output 节点的输出过程按依赖关系合并成一个“主图”执行

这就是 Output Graph:一个生成出来的 master graph,内部复用每个节点自带的子图,最终形成“包含多个 sub-graphs 的 graph”。


ProductIO Panel:在一个面板里管理 Product-Node 连接

当越来越多节点被 Productize 后,团队需要一个地方统一查看和管理这些连接关系,于是做了一个“表格式”的 Python Panel:

  • 基于 Houdini 的 node search,把场景中所有 Productized nodes 列出来
  • 支持按 node type / name / PRI 等过滤
  • 对 Output 节点:支持选择多个节点 → 生成 Output Graph → 一次性执行
  • 支持把节点上的部分参数“标记出来”,执行前临时在面板里集中调整(不必改 Qt 代码)


作者的反思与后续方向

ProductIO 的设计在很大程度上是“为了平滑迁移”:

  • 尽量把新概念藏在背后
  • 尽量让艺术家继续用熟悉的操作方式

但作者也坦诚:这种做法可能会牺牲一定的“系统优雅性”,带来技术债;随着团队对 Conduit 更熟悉,未来可以考虑减少 Product Properties 的参数数量,降低前端复杂度;同时 PDG 仍会是核心,可能进一步往“TOP 友好”的方向演进,让用户更直接地掌控流程。


我自己的小结:这套思路的可迁移之处

这篇文章我觉得最可借鉴的不是“某个具体工具”,而是它的拆解方式:

  1. 先统一抽象(Product / ProductItem / Input / Output)
  2. 再统一接入方式(Mixin 的 Product Properties)
  3. 最后才是体验与执行(Output Graph + Panel)

当你希望把一个版本化的数据系统接入 DCC 时,如果你一开始就从“给某个节点写适配”入手,规模一大就会回到维护地狱;反而是把“接入点”抽象成统一的 node-level 能力,才有机会让工具持续生长。

本文采用 Creative Commons BY-NC-ND 4.0 协议进行授权。

BY-NC-ND: 署名-非商业性使用-禁止演绎

End of Article