官方文档:Introduction to TOPs
总览
通过构建TOP节点的网络,你可以指定要完成什么工作,以及怎样操纵这些工作的结果。TOP节点
会生成 工作项(work item)
,它们将会完成特定任务和(或)在属性(attributes)
中存储信息。
有多种TOP节点,但是主要的两种类型是:
- 处理器(processor) 型节点将生成新的
work item
。 - 分割(partition) 型节点将创建
work item
之间的依赖关系,所以它们将会等待直到partition中所有work item
都完成。
一个TOP节点网络可看做是一个菜谱,其中包含:
- 生成
work item
- 在processor中高效运行它们(在单个机器中或者渲染农场中)
- 指出依赖关系,以便可以尽可能地并行。
这个菜谱 就是所谓的PDG(Procedural Dependency Graph,程序化依赖网络)。它描述了需要完成的work item
以及它们之间的依赖关系。
例如,现在要制作一个城市,这其中包含了多个work item
,它们之间也有依赖关系。通过建立它们依赖网络,TOPs可以:
- 找到更高效的方式来cook出它的最终结果。
- 当有变化时,它可以找到最少的 必要的工作。因为你已告诉了它依赖关系,它可以判断出哪一部分依赖于变化的东西。
作为Houdini的一部分,TOPs致力于高效地完成任务,例如:仿真模拟、渲染、合成。
然而,它通用于任何可以划分为独立项目并有依赖关系的任务。
使用TOPs工作
TOP节点UI
关于界面的更多信息,可见PDG node network interface
Processors(处理器)
Processors可以生成新的work item
。
基于传入的work item
,Processors可以生成多个work item
。(一生多又称为“fan-out”)
一个Processor节点——
- 既可以根据节点参数从零创建
work item
。 - 也可以基于输入节点传来的
work item
来生成新的。
许多节点同时以这两种方式工作。
一个Wedge节点如果没有输入,则会根据参数中指定的Wedge的数目来生成work item
;如果有输入,则创建的work item
的数目将是Wedge的数目乘以输入节点传来的work item
数目。

当Processor创建work item
是基于一个“父项”来创建一个“子项”时,它将会传递“父项”的属性
。因此work item
可以将结果顺流而下传递。
Mappers
Mappers为网络中原本不相关的work item
之间建立依赖关系。在正常情况下,它们通常是不必要的。
使用的情况例如:
- 你在两条不同的节点链中创建任务,但你想要告诉系统:其中的一条链上的任务实际上依赖于另一条链上的任务完成。
partitions(分割)
partition节点将基于多个不同的标准把输入的work item
们组合在一起。PDG以这样的方式将任务中的多个“碎片”组合为一个“整体”以供后续处理。(多生一又称为“fan-in”)
不同partition节点将以不同的方式组合上游的work item
。
partition有两个效果:
- 它在分组的
work item
之间创建依赖关系,因此该partition直到组中的所有work item
都完成后才能继续处理。 - 它(可选地)将分组的
work item
的属性
进行合并。例如,所有从partition创建的work item
都将接收这一组的合并的输出文件路径,作为他们的输入属性。
最常用的partition节点是 Wait for All 。它将所有输入的work item
都组合为一个partition,导致必须等待所有上游的work item
都完成之后,才能继续前进。
你可以基于不同的标准来做partitions,例如:
- 基于属性。比如将同一帧的所有任务都组合为一组。
- 基于自定义的函数。
- 基于空间。比如当你在地形上散布树木的时候,你可以将地形划分为网格,然后将一个小块上的所有项目都组合到一起。
就其本身而言,partition节点中的项目不会做任何工作,它们仅仅是保存着一组work item
的合并信息,使得后续的操作可以操作合并的信息。
Schedulers(调度器)
Scheduler节点是实质上负责运行work item
中可执行内容的。
- 不同的Scheduler类型代表了运行可执行内容的不同方法。例如:Local Scheduler 使用本地机器的线程池,而 HQueue Scheduler 将可执行内容放在了HQueue渲染农场中。
- 你可以在一个TOP网络中有多个Scheduler节点,从而可以根据情况将网络设置为以不同的方式进行Cook(例如,测试时使用本地机器,夜间时使用农场)
TOP网络默认的Scheduler将在参数中指定:
简单的TOP网络例子
下面简单的图示描绘了一个基本的网络,它的目标是以不同的质量级别来渲染出动画的五帧,并将每一帧的不同质量的图拼接合并,以此来创建对比图,使我们可以更方便观察出不同质量的区别。
- 使用 Wedge节点 生成四个
work item
,其中不包含实际任务,只包含变种信息(比如,Mantra渲染器不同的像素采样参数)。 - 加入ROP Mantra Render 节点,设置帧的范围为从1到5。这将为每个“父项”生成5个新的
work item
,而变种的属性也将传递到新的work item
中。 - Partition by Frame 节点 将相同帧序号的
work item
分组为一个partition。这将使一帧中所有的变种都完成之后才能继续下一步。 - ImageMagick 节点 生成新的
work item
将每一帧的五个变种图像拼接合并到一起,做成一个“对比图”。(当然,我们还可以使用 ROP Composite Output 节点来为对比图中的每个子图像添加一些文字,用以说明所用的设置) - Wait for All 节点在末尾,用以等待所有
work item
的完成。你可以在之后继续添加新的work item
,用以运行那些必须在“主要”工作完成之后才能开始的任务,例如:工作完成之后的后渲染脚本,或者给用户发提示等等。
参阅常用TOP节点来获取更多信息。
Work items
TOP网络中的每个Processor节点都会生成一定数量的work item
。 一个节点所创建的work item
可以从界面中节点的内部看到(有关更多信息,请参见PDG node network interface)。
许多work item
代表着某种“作业(Job)”,即在单台计算机或渲染农场中的进程中运行的脚本或可执行文件。 但是,也有些work item
的存在只是为了保存属性
而存在,实际上并不需要完成工作。
例如:
- HDA Processor 节点创建的
work item
代表着一项工作:他们对输入的一个HDA文件进行Cook。 - 而 File Pattern 节点创建的
work item
只是保存一个匹配的文件路径,是下游的处理器需要根据这些文件名进行一些操作。
Attributes(属性)
work item
包含着属性
,它们就是信息,类似于Houdini几何图形上的属性(比如一个点上的属性)。 与work item
关联的脚本或可执行文件可以读取属性
,以此来控制其执行的工作。 属性将从“父项”传递下来,因此你可以使用属性
使work item
的结果影响其“子项”、对子项进行分组的partition、并通过网络向下传递信息。
虽然,可以写自定义的节点来读取属性
并控制work item
的生成。
然而,属性
最常见的用法还是——在“TOP网络中”或“TOP引用的外部Houdini网络中”的节点的参数中,引用属性。例如:
- 你想使用不同的渲染质量。可以使用 Wedge节点 来创建名为pixelsamples的
属性
为不同值的work item
。 然后,在ROP Mantra Render 节点中,就可以写 @pixelsamples 这样的字符串来引用先前的属性
,并将其值设置到 Pixel samples 参数中。 - 你还可以在TOP网络调用的外部资产/网络中引用
work item
的属性
。 例如,HDA Processor为每个work item
进行Cook。 你可以在HDA的参数中使用 @attribute 来引用从work item
中提取的值。
你可以使用 @attribute.component 来引用向量的一个分量,其中 component 是从0开始的数字,或者x、y、z(分别等于0、1、2)。 例如 @pos.x 或 @pdg_output.0 。 你还可以使用pdgattribvals将属性数组的所有组件引用为以空格分隔的字符串。
节点,以及自定义的节点可以加任意的属性
。
而work item
还有一些内建的属性,可以在任何情况下访问。
静态 与 动态
静态:
有一些work item
在TOP网络开始运行之前,就已经基于节点的参数计算出需要的数目了,这些被称为静态的 work item
。
例如,对于一个没有输入的ROP Mantra 节点,它会为每一帧创建一个用于渲染的work item
。渲染的帧数将在参数中设定。所以work item
的数目可以在提前就知道。
如果节点会为每一个传入的work item
创建一个新的work item
,则这些work item
也被视为是静态的。
电影的工作流往往是基于“帧”的,由于提前知道帧数,所以往往生成静态的work item
。
动态:
有时,work item
只有在运行时才会被生成,他们被称为动态的 work item
。
游戏和特效的工作流通常更具动态性。 例如,基于人群代理的辅助模拟可能会根据每个图块中有多少代理,将人群划分为图块,而这只有在运行时生成人群模拟并读取文件后才能完成。
- 一般经验——静态胜于动态:因为
work item
的数量是可见的,所以你可以了解要完成的工作量,而Houdini可以给出更准确的完成百分比估算。 - 然而,根据工作流程,动态的 work item 是不可避免的,实际上,几乎整个网络都可能是动态的。例如,在一个游戏工作流程中,你从曲线生成一个关卡,你不知道需要多少的运算量,因为你的曲线可能会与其他曲线相交,曲线可能会与图块相交等等。
- 在某些情况下,Houdini无法分辨工作是否是静态的,于是为你提供动态还是静态的选择。在这种情况下,标记为动态始终是安全的,因为TOP网络始终可以在运行时确定需要哪些
work item
。但是,如果已知work item
是静态的,则将节点标记为静态的可以获得作为静态项的优势。 - Wait for All 节点 可以将动态数目的
work item
转变为静态的数目(1个),其他的partition节点也可以将动态数目转变为静态数目。这些情况都应该被自动设置,而非手动设置。 - 某些processor 节点具有“ Work item generation”菜单,可让您选择“静态”,“动态”或“自动”(“自动”表示“如果此节点能够静态生成,或者没有输入,则生成静态”)。 如果processor只能动态工作或只能静态工作,则它们将缺少此选项。
- 一些partition节点具有一个称为“Use dynamic partitioning”的参数。 当partitions取决于动态生成的信息时,将其打开。 如果partitions仅取决于最接近的上游静态
work item
中“已知”的信息,则将其关闭,在这种情况下,就可以静态计算partition。(如果节点的工作方式只能动态或只能静态,则节点可能不提供此选项。)
提示:
如果你的TOP网络中没有缓存结果(节点内没有work item
),则可以在网络编辑器中选择“ TOP”▸“ Generate Static Work Items”以生成所有静态已知项。 这通常可以帮助你了解网络中涉及多少工作,而不用实际进行Cook。
Managing jobs
官方文档缺失,todo。