原文:https://www.andreaskj.com/creating-and-animating-a-bird-in-houdini-solaris-feather-export-hda/
在 Houdini 20 的尾声,我终于决定深入研究这次发布里最重要的新功能之一——全新的羽毛系统。这个主题信息量很大,我在摸索过程中学到了很多东西。希望把这些经验整理出来,能对你制作自己的鸟类或其他生物有所帮助。
本文会覆盖从 Groom、绑定(APEX)、角色 FX、到在 Solaris 中使用 Karma XPU 渲染与着色的完整流程。鸟类制作很有趣的点在于:你会同时接触到 Houdini 里多个领域的工作流,以应对羽毛这种复杂资产的创建与模拟。
请注意:本文里的「绑定/APEX」相关内容在 Houdini 20.5 发布后才会完整落地。我有机会提前测试了部分 Houdini 20.5 的新功能,其中对 APEX 绑定工作流的增强非常显著,尤其是对鸟类这类带 groom 的角色。
话不多说,让我们开始制作一些“羽毛朋友”。
Feather Atlas
Feathers in Houdini(Houdini 里的羽毛数据)
下面的章节里我会频繁提到 barb 和 shaft:barb 是从羽毛羽轴(quill/shaft)上长出来的一根根细丝;shaft 则是羽毛中间那根羽轴/主轴。
Houdini 的新羽毛系统,提供了一种非常省资源的方式来存储原本会非常“重”的几何数据。你可以选择两种羽毛表达:
- Uncondensed(非压缩):原始几何,每一根 barb 都有独立的几何。
- Condensed(压缩):只保留 shaft 本身为原始几何;每根 barb 的 CV/点位则存为 shaft 每个点上的一维数组属性(例如
P_barbl和P_barbr)。数组长度为 x,其中 x = (每根 barb 的点数) × 3(对应每个点的 x/y/z 坐标)。同时还会有诸如barborient、uv_barbl、uv_barbr等属性用来描述 barb 的朝向与 UV。
尽管 barb 不是“原始几何”,viewport 依然能为你绘制它们;而由于数据结构更轻,渲染与交互也能更高效。

一根 condensed feather:在 Geometry Spreadsheet 里可视化它的点以及部分属性。
好消息是:你可以在 uncondensed 和 condensed 之间自由来回转换,比如使用 Feather Match Uncondensed SOP 和 Feather Uncondense SOP 等节点在两者之间切换,从而在不同阶段选择更合适的表达方式。不过一般建议在开始 groom 之前回到 condensed(除非你只想做少量用于特写的羽毛)。
另外请注意:要在 viewport 里渲染 condensed feather,需要在你的
Geometry
节点中开启
Shade Open Curves in Viewport
否则在 condensed 状态下你看不到 barb。

Shade Open Curves in Viewport 选项。
绘制一根羽毛(Drawing a feather)
在 Houdini 里画羽毛很简单,也很偏“美术友好”。最容易的生成方式是使用 Feather Shape Organize SOP。
该节点的第一个输入接收一条 Shape Curve:本质上就是羽轴(shaft)+ 羽毛轮廓线。为了得到更稳定的结果,我建议从羽轴底部开始画,先把那条 curve 画出来。
在我的测试里,我都是用 Curve SOP 手绘所需曲线;理论上任何能生成 curve 的 SOP 节点都可以作为输入。

Feather Shape Organize 的网络示例。
第二个输入用于 profile curves(可选,但强烈推荐)。它们也是曲线,用来描述羽毛不同区域 barb 的整体流向(flow)。
当你把这些曲线接入 Feather Shape Organize SOP,它会自动创建 Houdini 生成羽毛所需的 groups。画这些曲线时可以比较随意,细节会在后续章节再补。建议使用真实羽毛参考来描绘(后面会讲)。

Shape Curves、Profile Curves 以及两者合并后的结果(按顺序)。
最后,把 Feather Shape Organize SOP 的输出接入 Feather Template from Shape SOP,你就能得到第一根 condensed feather。
在这个节点上,你也可以设置分辨率、宽度、名称(name)和 side。建议把 Side 和 Name 设置成有意义的值(例如 side 通常用 l),这在后续 groom 时会很重要。
另一个需要特别注意的参数是 Barb Segment:确保你的所有羽毛都使用相同的 Barb Segment 值。因为合并不同 Barb Segment 的羽毛可能会产生不可预期的结果(我的理解是:这个参数决定了 P_barbl、P_barbr 等数组属性的尺寸,Houdini 在合并不同尺寸属性时不知道该怎么处理)。
这里提到的“属性尺寸”指的是它包含多少个 component。例如:24 float 有 24 个分量;vector 有 3 个分量,以此类推。
很好!目前这根羽毛还比较简单,我们开始加入一些细节。

使用 Feather Template from Shape SOP 生成的羽毛。
添加细节(Adding details)
默认情况下羽毛在视觉上往往不够“有趣”,你需要加入噪声、clumping(结簇)等各种细节。做法很多(尤其是 uncondensed 工作流),但对多数情况而言,你会主要使用专门的羽毛节点,比如 Feather Noise 与 Feather Clump。
当然,你也可以使用你在 Houdini Groom 里常见的 Guide Process 节点。
我的做法是把上述方法混合使用来达到目标效果。这个过程更偏艺术创作,最终结果也高度依赖你想要的风格。建议多试不同节点组合,找到你自己最顺手的工作流。

一个羽毛示例:使用多个羽毛与 groom 节点叠加细节。
如果要给一个更具体的“小技巧”,我在 Attribute Randomize 里生成一个用于控制 clumping 的属性,然后用它去驱动 Feather Clump 的 Split Attribute,效果很好。
我把 Attribute Randomize 设置为只输出 0 或 1(表示 clump / 不 clump),再接到 Feather Clump 的 Split Attribute 上。

用 Attribute Randomize 生成 split attribute。你也可以把多个 Attribute Randomize 组合起来(Operation 设为 Set Value)。

Split Feather Clump。
另一个非常实用的技巧是:善用羽毛与 guide groom 节点里的 Ramp 按钮,它能让你控制节点沿羽毛表面的影响分布。我在制作里经常用它。使用 Guide Process 节点时,也值得看看 Masking 选项卡。

Feather Noise。
创建羽毛图集(Creating a Feather Atlas)
制作鸟类时,你通常不止需要一种羽毛。因此你会构建所谓的 “feather atlas”(羽毛库/羽毛图集):也就是针对鸟的不同区域准备一组羽毛集合。
我强烈建议为此找到优质参考。我使用了 Feather Atlas 与 Featherbase 的组合。它们都免费,而且覆盖了很多物种,有时还附带尺度信息。
做法是:把参考图加载到 Houdini 作为背景(viewport 按 D,到 “Background”),然后在 top view 上描绘曲线。你不需要太担心你在世界空间里画的位置:开始 groom 时 Houdini 会自动确定羽轴根部的位置。

在 Feather Atlas 的图集上描绘羽毛几何。
开始画羽毛之前务必检查场景尺度(scale)!很多羽毛图集参考图里都会带有尺度标尺。
在我的例子里,我建立了 4 组羽毛,每组包含 5–10 根:primary feathers、secondary feathers、tail feathers,以及一些 down feathers(绒羽)。然后把它们合并为一个输出,用 File Cache 缓存起来,避免每次都重新计算网络。

我在 groom 中使用的多组羽毛集合。

Feather atlas 网络。
Grooming
有了羽毛库之后,我们终于可以开始 groom 了。这同样是一个很艺术的过程,而且实现方式有很多。我在乌鸦资产里主要用了两种技术:手动(manual) 和 散布(scattered)。后面我也会展示我是如何把 groom 导出为 USD 并为渲染做准备的。
在我的制作里,我把 groom 拆成多个部分分别导出(翅膀、身体、尾巴等)。主要原因是:我发现“合并羽毛”不太稳定。虽然能做到(通常在做 Feather Template Interpolate 之前先合并 guides 会更稳定),但很容易出现怪异 artifact 或羽毛损坏。
因此我选择每个区域单独导出,再在 Solaris 里组装渲染。若想在 SOPs 里预览合并结果,可以用 Merge Packed。这个做法对我而言更稳定。如果你有更好的合并经验也欢迎交流。
手动 Groom(Manual Grooming)

手动 groom 的基础网络概览。
手动工作流的核心是:用 Guide Groom 在 base mesh 上手绘羽毛 guide,然后把这些曲线插值为羽毛。这很适合翅膀、尾巴等需要精确排布的区域。
流程很直接:添加 Guide Groom,把网格接到该节点的第二个输入(注意是第二输入)。然后需要调整一些参数,让它进入羽毛工作模式(因为它原本是为毛发/毛皮设计的)。
首先在节点参数的 Feathers 选项卡中开启 Create & Output Feathers。然后把上一节制作的羽毛库路径填到 Template Geometry SOP。再往下的 Template Group 用于选择你想要散布的羽毛:它会识别你之前给羽毛设置的 name。改变这里不会影响你已经画好的羽毛,只会影响之后新放置的羽毛。
接着,在 Orientation Attributes 里开启 Create and Maintain orient Attribute,把 Orient Attribute Name 设为 barborient。这非常关键:它决定 barb 的方向,并且需要在整个 groom 过程中被维护。
你也可以设置 Active Name 便于后续分组;或开启 Mirror Groom 来同时编辑左右两侧——这些都属于可选项。

Guide Groom。
现在你就可以开始画羽毛了。建议先用 Draw 工具起步,再根据需要用下拉菜单里的其他工具做调整。

Guide Groom。
我也建议把你的 base mesh 做 template(按住 w 拖到 mesh 节点上,或在包含 base mesh 的节点上 Ctrl+点击 template 按钮),这样在 groom 时你能看见底下的模型。

Guide Groom。
散布式 Groom(Scattered Grooming)

散布式 groom 的基础网络概览。
散布式工作流的思路是:先在网格上画少量 guide curves,然后用 Hair Generate 基于这些 guides 在周围生成更多曲线。这是快速覆盖大面积表面的方式,非常适合身体、头部等大面积区域,但它需要更多设置。
起手式与手动流程一致:先用 Guide Groom(与上一节相同设置)画 guide curves。
然后你需要两个额外节点:Hair Generate 和 Guide Interpolation Mesh。
Hair Generate:根据输入 guide curves 生成更多曲线。Guide Interpolation Mesh:为插值生成一个低分辨率 proxy mesh,其中包含index和weight属性,供Hair Generate进行 guide influence 的插值。你可能需要调整Guide Interpolation Mesh的Max Triangle Size来获得更好的结果。
对 Hair Generate:把 Guide Groom 的 skin 输出接到第一个输入,把 guides 输出接到第二个输入(顺序有点反直觉);最后一个输入接 Guide Interpolation Mesh 的输出。
然后在 Hair Generate 的 Guide Weights 中启用:Compute Weights Using Skin Coordinates、Use Interpolation Mesh,并把 Skin Guide Method 设为 Weight Array Pair (guides and weights)。
你可能还想关闭 Grow Unguided Hair,这样它只会在你画了 guides 的区域生成曲线;否则会把整个网格都填满。

Hair Generate 参数示例。
完成上述设置后,你主要会调的是 Density / Total Count,它决定了羽毛实例的密度。你也可以用密度属性来控制(任何 float 属性都行,例如用 Paint SOP 画一个 density),从而在表面不同区域获得不同密度,这很实用。
把 Hair Generate 的曲线插值成羽毛(Interpolating Feathers)
Hair Generate 的输出仍然是曲线,我们需要把它们变成真正的羽毛。做法是接一个 Feather Template Interpolate:它会根据曲线上存的属性以及羽毛库,把输入曲线插值为羽毛。

Feather Template Interpolate。
这个节点参数很多,你可以重采样羽轴与 barb,用于优化。还有一个 Interpolate UVs 开关,我建议开启。

Feather Template Interpolate。
在它之后,我经常会再接一个 Feather Resample 做进一步重采样。以及加一个 Feather Visualize,把 Barb Mode 设为 Curve:主要用于确保我们观察的是完整羽毛,而不是 meshed 版本。
如果你希望更快预览,可以做一条分支,把另一个 Feather Visualize 的模式设为 Surface,通常 viewport 计算更快。
你也可以做更全局的外观调整,例如加 Feather Noise 做破碎感,或用 Feather Width 调整 barb 宽度。羽毛工作流很灵活,同类节点可以在不同阶段反复使用。

乌鸦资产里使用的部分 groom 网络。注意我在手动 groom 下也放了 Feather Template Interpolate(可选,我主要用它做 resample)。

最终 groom 在 viewport 中的效果。
在 Solaris 里渲染(Rendering in Solaris)
SideFX 提供了一个非常优雅的方式来在 Solaris 里渲染羽毛:自定义的 Feather Procedural。但要完整使用它的功能,我们必须先正确导出 groom。下面我会讲我的做法;同时我也提供了一个自制 HDA,用来把流程自动化。它可能需要你在自己的 pipeline 里做些调整,但希望能帮你省点时间。
Procedural 简介(Introduction to Procedurals)
Procedural 是 Houdini 中一类特殊节点:它们允许在渲染时生成几何。它们很有用,我也希望未来写更多相关内容。今天我们聚焦 Feather Procedural。
初次使用 procedural 时可能会觉得“有点怪”:因为它不会自动影响你在 viewport 里看到的渲染结果。默认情况下,procedural 只会在你进行真正离线渲染时才被激活,比如通过 husk(用于渲染 USD 的 Houdini 命令行工具;当你使用 USD Render ROP 时底层就是调用它)。
如果你希望在 viewport 中预览 procedural 的效果,可以用 Houdini Preview Procedurals 节点,它会在 viewport 工作时调用 Houdini Procedurals。注意:它不会把结果 bake 到 USD 文件里,只是 viewport 预览。
Feather Procedural
我们来看看 Feather Procedural 的结构与参数。
它的核心目的,是把羽毛曲线转换为真正的羽毛几何。原因与 condensed feathers 的数据结构有关:当你用 SOP Import 把 condensed feather 导入 Solaris 时,默认只会得到曲线。我们需要 Feather Procedural 来根据之前提到的属性(如 P_barbl、barborient 等)插值生成 barb。归根结底,这是为了优化数据 I/O。
除此之外,你还可以用 Feather Procedural 基于一个 proxy “deformer” 网格来驱动羽毛动画(后面会讲)。

把 Feather Procedural 放到 Solaris 里:如果不启用 procedural 预览,你只会看到曲线。
Feather Procedural 最多有 4 个输入,其中 3 个需要你用多个 SOP Import 从 SOPs 导入。下面是它们的作用概览:

Feather Procedural。

Feather Procedural。
Procedural Prim:这是唯一不需要从 SOPs 导入的 primitive。建议在 Solaris 里放一个 Primitive LOP,创建一个空的 BasisCurves primitive。它是整个 procedural 的“核心”,负责指向其他数据,并定义羽毛的全局设置。

Primitive LOP:BasisCurves。
Groom Rest:加载 groom 的输出曲线。你需要先用 SOP Import 把 groom 导入 Solaris,并在 Feather Procedural 中把该路径指向对应 prim。
Deformer Rest(可选):前面提到的 proxy mesh,一般在 SOPs 用 Feather Surface 生成,然后用 SOP Import 在 Feather Procedural 之前导入。
Deformer Anim(可选):这是 Deformer Rest 的动画版本。Feather Procedural 会根据它来驱动“真实”羽毛几何的动画。对动画/模拟羽毛 groom 来说非常优雅:FX 只需要覆盖 Deformer Anim 的网格动画,渲染场景就能自动连接起来。只要你控制好 Deformer Rest 的分辨率,这个工作流也会非常轻量。
如果你按上述方式搭好 Feather Procedural 并接上 Preview Houdini Procedurals,你就能在 Solaris 中渲染羽毛。下面是一个示例网络。对每个 groom 导出你都需要做一次类似配置。
我建议用
Configure Primitive LOP
把 _groom 和 _deformer 这类 prim 设为 invisible 或 preview render purpose,否则它们也会被渲染。你真正想渲染的是下面示意中的 _procedural prim。

渲染羽毛的示例网络。注意:如果你只想在 viewport 看到羽毛,才需要 Houdini Preview Procedurals。
自动化流程(Automating the process)
我知道这信息量很大,尤其是如果你对 Solaris 还不熟。因此我做了一个 HDA:你可以把它放在 SOPs 里 groom 的末端(接入 groom 和 mesh/skin),在 Cache Name 里指定名字,然后点击 Save to Disk。它会把 USD 导出到 $HIP/geo/grooms/,并把结构都搭好。之后你只要在 LOPs 用 Sublayer LOP 加载 USD,再加一个 Preview Houdini Procedural,就能直接渲染。
这个 HDA 也会自动创建 deformer meshes 的设置:如果你把 deformer_anim prim 从 LOPs 导回 SOPs 做动画/模拟,再导回 LOPs,只要你维护好 全部属性,就能自动得到能工作的动画羽毛。
该节点也兼具 file cache 功能,让你能缓存 groom 而无需重算。
即便你想从零搭建,我也建议你检查一下这个 HDA 的内部网络:当上面某些步骤不清晰时,参考它会很有帮助。
你可以在这里下载(Houdini 任意 license 都可用,包括 FX):

Feather Cache 节点。
说完导出,我们来看看着色。
Shading(着色)
Karma 自带了很不错的 hair shaders,CPU 和 XPU 都能用。本节会讲我最后是怎么用它们的,以及有哪些需要注意的点。这里默认你在 Solaris 中的层级结构类似下图(如果你使用了我前面分享的 Feather Cache HDA,输出会是这种结构)。

Solaris 中羽毛 groom 的层级示例。
第一步是用 SOP Import 把 base mesh 导入 Solaris;然后通过 Sublayer(如果你用 HDA 导出)或按上节方式搭网络导入羽毛。开始时,你在 viewport render 里可能会看到类似下面的效果。

Viewport render(未使用 Houdini Preview Procedural)。
如前所述:如果不放 Preview Houdini Procedurals,你不会在 viewport render 里看到羽毛。但如果你通过 USD Render ROP(或命令行 husk)做离线渲染,即使没放 Preview Houdini Procedurals 也能渲染出羽毛。主要原因是性能:Houdini Procedurals(比如 Feather Procedural)cook 需要时间,你可以选择在需要时才启用它。
在 production 中,我通常会保留一条单独的分支启用 Preview Houdini Procedurals,只在需要判断最终效果时查看,不影响其他工作。

Preview Houdini Procedurals。

Viewport render(启用 Houdini Preview Procedural)。
开始做着色:先放一个 Material Library,进入后创建 Karma Material Builder。默认会带一个 MtlX Standard Surface,把它删掉,然后换成 Karma Hair 或 Karma Fur。两者都很好;Karma Fur 是 Karma Hair 的扩展版本,实现略不同,包含更高级的“光在毛发内部散射”的建模。本例以 Karma Fur 为主,但大多数技巧对 Karma Hair 同样适用。
分配材质时你必须 target procedural primitive:如果你用我的 HDA,它的名字是
<groomCache>_procedural
Karma Fur 参数
Color

Karma Fur 的 Color 选项卡参数概览。
这是最主要需要调的部分。关键参数通常是 Melanin、Thickness 与 Base Color。
Melanin 是毛发中天然色素,用来决定毛发的颜色和深浅。对很多毛发资产很方便,但在羽毛上,我发现经常更适合把它关掉,让颜色完全来自纹理贴图/Base Color。要禁用 Melanin 影响,把 Melanin 设为 0 即可,此时 shader 会使用你的纹理/Base Color。
Thickness 用来控制 shading 层面“毛丝”的粗细。注意:它 不会 改变实际几何的宽度,只影响着色外观。数值越低,barb 越接近白色。我在乌鸦上用 4 效果不错,但你需要根据自己的 groom 和风格调整。
Base Color 就是毛发本色(或者在 Melanin 较高时相当于染色)。我用羽毛的 UV 在羽轴方向做了一个 subtle 的 ramp,让羽毛颜色有轻微变化。下面是默认 UV 的可视化。我从 MtlX Texture Coordinates(可视化中绿色部分)里取 V 分量(用 MtlX Separate Vector 2),再接到 Karma Ramp Const。

默认 UV:红色与绿色通道可视化。

Base Color。
Cortex

Karma Fur 的 Cortex 参数概览。
Cortex 相当于 Karma Hair 的 Specular。我觉得这是最难调的一部分,因为羽毛高光在不同光照条件下变化很大。我也不敢说找到了最佳组合,但会把当时的经验分享出来。强烈建议你大量尝试这些参数来找到平衡点。
关键参数包括 Shift、IOR、Roughness,以及一定程度上的 Cuticle Reflectance(这是 Karma Fur 特有的)。你也可以在两处启用 Roughness Anisotropic,从而控制光在毛丝中传播时的“模糊/拖尾”行为(通过 Roughness Azimuthal 调整)。这不是必须的,但我觉得微调一点很有帮助。
Shift 是 cuticle 角度,用来决定高光沿着毛丝/羽丝出现的位置。我用 -0.2 效果还不错。cuticle 是毛发最外层,由重叠的死细胞片组成,如下图。它与 IOR 紧密相关;我在本例里保留默认 1.55。

Wikipedia 上的人类毛发 cuticle 图片。
Roughness 与其他 shader 类似,用来控制高光粗糙度。我这里用了稍高的值,避免羽毛看起来太镜面;也加了一点 Roughness Randomize,让每根 barb 的高光有轻微差异。
Cuticle Reflectance 是另一个调 cuticle 高光的参数,用来建模 cuticle 的“片状结构”。我把它稍微提高,让某些区域高光更紧;并用 Extra R Color 加了一点蓝色倾向,试图模拟乌鸦羽毛在某些角度会出现的薄膜蓝紫色观感。未来我可能还会重新研究这一部分,但作为起点它已经不错了。这一节也有自己的 Roughness 参数。
以上就是我在乌鸦羽毛 shader 里真正动过的参数。当然也建议你探索一下 Medulla(毛发最内层)以及 Advanced;Diffuse & Specular 也值得看看,但更多是给你做额外艺术控制的。
Rigging & Animation(绑定与动画)
Houdini 20.5 在 APEX 绑定系统、以及带 groom 的角色绑定方面做了很多增强。本节会讲我是如何利用这些新功能来为乌鸦做动画与绑定,重点是新的 APEX Add Groom 节点。
为 APEX 做准备(Preparing for APEX)

骨骼创建与 skinning。注意:PolyFrame / tangentu 的加入。
像往常一样,我们需要把 skeleton、skinned mesh、guide skeleton 用 Pack Folder 打包,才能开始 rigging。为了节省篇幅这里不展开;但你需要添加一个关键改动:
在 mesh 上增加一个
PolyFrame
节点来生成
tangentu
属性。这必须加在你的网格上,是
APEX Add Groom
正常工作的必要条件。

PolyFrame SOP:生成 tangentu 属性。
APEX Rig 搭建(APEX Rig Setup)

APEX Rig 网络概览。
来看乌鸦 rig 的搭建。你可能注意到:我几乎没有使用自定义 APEX rig components。很大原因是 SideFX 提供了一批非常好用的 Autorig Component presets:以前只有少数几个,现在变得更完善,能覆盖大量常见绑定需求。下面按步骤拆解。
FK / Bind
首先用 fktransform Autorig Component 设置 bind skeleton(以及必要时暴露给动画师的 FK 控制)。它负责初始化 bind skeleton,也是很多其他 Autorig Components 的前置依赖。

fktransform。
Bonedeform
顾名思义:确保 bind skeleton 能正确变形你的 skinned mesh。

bonedeform。
Main Ctrl / FK Ctrls / Toe FK / Wings
这些部分我放在一起讲,因为它们使用的都是 transformdriver Autorig Component,逻辑也相似:用它来定义多个部位的自定义 FK 控制。
transformdriver 可以基于输入 guide skeleton 生成一个新的 control(如果对应 joint 存在),或者基于 bind skeleton 中已有的 bone 生成 control。
在该节点里,每个 setup(一个节点可添加多个 transformdrivers)会有 5 个 tabs:
Settings
决定 control 影响 transform 的哪些部分。注意这不是动画师最终能看到/能调的通道,而是你在 rig 逻辑层面要驱动哪些变换。多数情况建议全开。

Settings tab。
Driven
指向 bind skeleton 中要被 control 驱动的 joint。

Driven tab。
Control
最需要调的部分。driver 是你要创建的 control 名称:如果 guide skeleton 里存在同名 joint,它会直接使用;否则它会创建新的 control。若要在此节点创建 control,你需要指定 driverguide(定义 control 的位置,通常用 bind joint),以及 driverparent(control 的父级,取决于你的层级结构)。

Control tab。
Tags 与 Shape tabs 用于添加 tags 与控制器形状。本例我没用 tags,形状是后面再统一定义的。
Spine / Neck / Tail
上述三部分我都用 spine Autorig Component 来搭 spine 系统。

spine
做法是:在 Driven tab 里填入 spine 的 bind joints,在 Controls tab 里配置你要的 controls,并根据你想要的行为把 controlhierarchy 设为 tangent 或 fk。我对 spine 用 tangent,对 neck 与 tail 用 fk。
IK Leg

smoothik
IK 腿的设置与我之前的教程很相似。主要区别是:我为鸟腿做了两段 IK——一段控制腿的前半段,一段控制后半段。因为鸟腿需要在两个位置弯折,我等于是把它当成有两个“膝盖”。
然后在末尾再加一个 transformdriver,把第一段 IK 的 ikhandle 约束到第二段上。这样我得到了一个很顺手的 IK 腿控制。

链式 IK 的效果。
可能有更聪明的做法,但这个对我的目的来说已经很好用。
Eye Lookat

眼睛 lookat 控制。
这是 Houdini 20.5 的一个很棒新增:lookat Autorig Component。它让你很方便地创建 lookat 约束,非常适合做眼睛。
设置很直接:你需要一个 target control(通常在 guide skeleton 里定义),然后指定 parent control 与要被 lookat 约束驱动的 joint。我这里设为眼睛 joint 本身。
你可能需要在 Settings tab 调整 transform 才能得到正确的行为。

lookat
APEX Add Groom
现在来到本次 APEX 绑定增强的重点:APEX Add Groom。它允许你把羽毛 groom(或普通 groom)的 proxy 几何直接挂到 rig 上。这样动画师在做动画时就能预览羽毛 proxy,甚至还能控制其中部分羽毛。
要让它工作,你需要加载两部分数据:groom curves 与 proxy geometry surfaces。如果你用我前面那个 HDA 导出 groom,可以在 LOPs 里做 LOP import,取 groom prim(曲线)和 deformer_anim(proxy mesh)。然后接一个 Unpack USD to Polygons,就可以了。
当然,你也可以直接从 SOPs 加载 groom;这里只是在展示一个适用于 USD production pipeline 的思路。

APEX Add Groom。
groom 与 proxy/deformer 上最重要的属性是
id
它必须在 proxy 和 groom curves 上一致,否则会得到奇怪结果或节点报错。
把数据接好后通常就能直接工作:选中 APEX Add Groom 并在 viewport 按 Enter,你应该能看到羽毛;拖动 rig 时它也会跟随(这就是前面 tangentu 属性的作用)。
最后,你还可以给羽毛本身加控制。APEX Add Groom 提供了一个很方便的方式为羽毛创建类似 ribbon 的控制系统:在 Control Groups 旁点 +,在 Group 旁点箭头,在 viewport 里交互式选择你要加控制的羽毛。下面是演示,实际用起来效果很好。

APEX Add Groom。
完成后,你可以用 File Cache 保存 rig,然后加 APEX Scene Add Character 与 APEX Scene Animate 开始做动画。动画完成后用 APEX Scene Invoke 抽出动画后的 mesh,再做模拟或导出。
通过
APEX Add Groom
添加的羽毛,会在
APEX Scene Invoke
的输出里作为一个独立的 key,默认叫
GroomSurfaces.shp
如果你想抽出曲线,也可以用
Groom.shp
这个 key。

从 APEX rig 中提取动画后的羽毛 proxy geometry。

带控制器的动画鸟。
在我的乌鸦里,我只把翅膀羽毛加进 rig;其他部位的羽毛在后续用 Guide Deform(或 Point Deform)基于动画网格做变形。整个流程都在 proxy geo 上完成,这样在 Solaris 里仍能用 Feather Procedural 基于 proxy 来驱动真实羽毛的变形(前面已经讲过)。
要让它工作,你只需要确保 Feather Procedural 里的 Deformer Rest 与 Deformer Anim 的拓扑与属性匹配。这样无论你是直接用 rig 驱动 proxy,还是做模拟,都可以把输出网格接到 Deformer Anim,Solaris 会帮你完成后续。

Houdini Feather Procedural。
结尾与工程文件(Conclusion & Project Files)
感谢你读到这里!写这篇博客对我来说非常有成就感,也感谢所有订阅与分享的人。
如果你想在 APEX/动画章节更新时收到通知,欢迎订阅我的 newsletter(下方)。
另外,应大家要求,我最近也开始提供工程文件。如果你有兴趣,可以在 Gumroad 获取本项目中 groom 部分的工程文件。除了能拿到 houdini 场景外,这也能支持我继续免费发布这些内容。
当然这完全是自愿的;博客文章仍会继续保持免费。