跳到主要内容

Houdini 高级话题


haowei.han@mthreads.com

这一章节我们主要讨论Catalyst FX Houdini 插件版本的高级使用流程,包括但不限于:Houdini DOP 原生节点混用,GPU VOP 可视化编程等内容。

关于节点命名

drawing

由于 Catalyst FX 是基于我们的物理引擎 AlphaCore 所开发的流体模拟产品,所以在 DOP 中所提供的节点均为 AlphaCore 类型节点,也就是节点前缀以:Ax 命名的节点,没有直接使用 Catalyst 作为命名前缀的原因和 Houdini Pyro FX 流体解算器内部底层节点很多是以 Gas 前缀开头类似。这里所出现的 AxField 前缀节点,是 AlphaCore 物理引擎所提供的流场计算节点,其功能层面也类似 Houdini DOP 提供的 Gas MicroSolver 系列节点组。为了方便大家在使用节点控制的时候,找到对应的湍流控制节点,这里给出对应表格数据。

湍流名称DOP 节点对应的 Houdini 流体计算效果
DisTurbAxField_UltraTurbDisTurbance
ShreddingAxField_UltraTurb (开启Advance 面板下的 Rotational Force 勾选)Shredding
CurlNoiseAxField_CurlNoiseTurbulence
ConfinementAxField_VorticityConfinementConfinement

DOP Control Workflow

Houdini 的 DOP 模块提供了大量和物理解算有关的计算节点组,并且很多艺术家过去多年的工作经验,也都是基于使用 Houdini DOP 节点组进行各种各样复杂效果的制作,所以我们在Catalyst FX 设计之初,就希望艺术家在使用Catalyst FX 的时候,还可以有一种高效的计算方式,继续使用 Houdini 原生的 DOP 节点组,这样可以在提高效果可控性的同时,进一步降低上手门口,做到在流程和体验的无缝切换。

drawing

如图(上) :在 Catalyst Solver 节点Advance 面板的 DOP Control 子面板下,找到 AllowDOPMicroSolver 勾选并开启,即可在 Catalyst Solver 节点内部的 DOP Network 层级使用 Houdini 原生自带的 DOP 节点组参与效果计算。否则,处于计算效率考虑的角度,解算器默认会忽略所有需要在 CPU 上进行计算的 DOP 节点,这一点设计和 Houdini Pyro FX 系统的 Minimal OpenCL 工作模式类似。

在打开 AllowDOPMicroSolver 参数设置后,我们来对一个基本的烟雾效果添加 DOP 节点来参与最终效果计算。

drawing

如图(上) : 双击 Catalyst Solver,进入解算器内部的 DOP 节点网络层级,创建Houdini DOP自带的 Gas Wind 节点,设置 WindScale 为2,再次解算可以发现燃烧的硝烟在 Gas Wind 节点的作用下,产生了沿X轴水平方向的飘散运动效果。

以上作为最基本的 DOP 节点使用流程介绍。当然,在 DOP 节点网络层级下使用 Gas MicroSolver 系列的湍流节点也是可以被允许的,只是这样做的性价比并不是很高。

drawing

如图(上) :这是一个并不科学的展示,虽然启用了 DOP Control 功能后,我们可以随意的使用 Houdini DOP GAS 系列的全套节点组,即便是用于产生流体动态细节的 Gas Vortex Confinement 也可以产生正确的效果。但是我们仍然不建议用户使用 DOP Control 来进行复杂且精细效果控制。这主要还是从计算效率的角度考虑,通常情况下 Catalyst FX 一个完整 step 的效果计算通常不会超过 100ms(10 FPS),而Houdini内不少 Gas MicroSolver 节点的单个节点计算时间就已经达到了这个量级,所以从体验的角度来说,容易产生用户在开启 DOP Control 功能后,感受到解算器工作效率呈现断崖式下降的糟糕体验。

当然,即便是在开启 DOP Control ,让 Gas MicroSolver 节点参与到 Catalyst FX 计算的情况下,解算器的整体性能仍然可以保证比 Pyro FX 快到 3~5倍以上。

DOP Control 的注意事项

由于 DOP 节点的计算是在 CPU 上完成,而 Catalyst FX 节点的计算是在 GPU 上完成,这导致使用 DOP Control 功能的时候,GPU 和 CPU 之间会存在大量的同步,以及数据传输问题,在一些应用场景中,会极大程度影响到操作流畅度的体验。

这里拿 MooreThreads MTT S4000 或 nVIDIA RTX 3060 这个级别的 GPU来举例,单个 256 * 256 * 256 精度的流场(1677 万 Voxels)数据回读,平均时间在 15ms 左右,而完整的速度场回读就会达到 45ms 的用时,在经过DOP的计算后,我们还需要把在CPU上的速度场传回 GPU,这会导致最终数据传输时间开销达到 100 ms 这个量级。

所以为了优化速度场传输的性能开销,我们开发了降采样回读编辑方法,拿一个 256 * 256 * 256 精度的速度场来说,我们会先对这个速度场进行降采样处理,先将当前的速度场精度降低到 128 * 128 * 128,然后在 DOP 节点网络的编辑中,始终是对这个精度降低后的速度场进行编辑操作,最终也是把在 DOP 中编辑好的低精度速度场上传回 GPU参与完整流程计算,这样整体的 IO 带宽开销,和 DOP CPU 节点的计算开销,都降低了 8 倍,也就是一个量级左右。

drawing

如图(上):在 Catalysts Solver 节点的 Advance 面板的 DOP Control 子面板下,启动了 AllowDOPMicroSolver 勾选后所激活的 DOP Velocity 下拉菜单,默认倍设置了 2x DownSample。经过和产品早期测试用户在实际项目中的试用反馈来看,使用 2x 降采样精度的速度场进行 DOP Control,在大多数应用场景中已经足够使用,所以这里速度场 2x DownSample 作为 DOP Control 的默认设置参数。如果一定存在特别复杂的应用场景,需要在 DOP 中编辑完整精度的速度场,可以将该参数由默认的 2x DownSample 模式,设置成 FullResolution 模式。

在实际的应用场景中,需要用户使用 Gas MicroSolver 参与流体效果调整的需求分为2类,一类是湍流(Turbulence)效果计算,如:使用多个 DisTurbance ,或 多组 CurlNoise 节点生成不同频率的湍流扰流细节。这部分的效果制作会给画面带来高频的细节变化,需要直接对原始的高精度速度场进行计算编辑处理,所以不适合使用降采样回读编辑方法。但这部分的效果我们都完成了对应GPU节点的开发,可以直接使用。而剩下一部分效果的 Gas MicroSolver 应用场景,就是用来对流体的大形态进行比较特殊的定制化控制。

如:使用让流体可以沿着在 SOP 中编辑好的曲线运动,或让风场的强度可以跟随高度的变化而产生简单的起伏,这些效果的作用力,都不需要使用精度过高的网格进行编辑。所以,这部分的效果大形控制更适合使用 DOP Control来实现,这里我们将展示一个由知名特效团队 MORE VFX 提供的测试案例,来进一步说明 DOP Control 功能中,高低频控制的概念。


MORE VFX | Gas VEX 翼尖涡流

drawing

如图(上):由 MORE VFX 提供的测试案例,飞机飞过的区域产生翼尖涡流的效果,该案例使用 Catalyst FX + GAS FieldWrangle 节点编写 VEX 脚本实现,接下来我们对当前案例的制作过程进行一个简单的介绍。

当飞机在空中飞行时,飞机机翼两侧的气流在尖端处相遇而形成的,空气从机翼的底部流向顶部,然后在尖端处汇聚,形成一个旋涡。这个旋涡看起来像是一条细长的线,绕着飞机的尖端不停旋转。这种特殊的气流现象,被称为翼尖涡流,是一种常见的空气动力学现象。

制作流程简介

翼尖涡流的制作流程和龙卷风很像,核心思路就是想办法让流体能够绕着一条曲线旋转,所以首先我们需要沿飞机飞过的路径构建路径曲线,然后再通过开启 DOP Control 功能,编写让流体绕着曲线旋转的 VEX 代码来实现翼尖涡流拖尾效果。

drawing

如图(上):首先使用 Ray 节点 将机翼投影到地面上,并使用 Extract Centroid 节点提取投影重心点,然后用 Trail 节点计算轨迹,使用 Time Shift 节点锁死到整个动画的最后一帧,并用 Add 节点将所有的点都链接成线,再添加 Poly Frame 节点计算出 tangentu 属性,作为曲线方向信息。如果得到的 tangentu 属性和我们需要的方向相反,也可以使用 Point Wrangle 对属性乘以 -1 取反。

drawing

如图(上):这样的曲线一共需要制作3条,除了演示的投影到地面的一条,还有左右两边机翼处的两条(红,绿),作为翼尖涡流的漩涡旋转中心线。

添加 Gas VEX 代码

在有了飞行轨迹曲线,和左右两侧的机翼运动轨迹曲线后, 我们就可以使用DOP Control 功能,通过 VEX 代码来实现流体绕着(红,绿)曲线旋转的形态。

drawing

如图(上): 针对前面已经制作好的3条轨迹曲线,这里一共要给流体解算器添加3个 Gas Field Wrangle 节点,分别将每一条曲线作为计算辅助输入完成最终速度场的计算。其中 centerDriven 节点的 Input1 读取运投影到地面的动轨迹,leftDriven 节点 Input1 读取红色左侧机翼运动轨迹,rightDriven 节点 Input1 读取绿色右侧机翼运动轨迹曲线。

添加的 VEX 代码如下

//centerDriven Node
int pr;
vector uv;
float dist = xyzdist(1, @P, pr, uv);// 选取 地面轨迹曲线
vector tangentu = primuv(1, 'tangentu', pr, uv);
float w0 = fit(dist, 3, 9, 1, 0);
float w1 = fit(dist, 0, 4, 0, 1);
w1 = pow(w1, 1.8);
w1 *= 3;
v@vel += tangentu*w0*0.5 + set(0,1,0)*w1*pow(fit(@P.y,-7,-5,1,0),1.8);
//leftDriven & rightDriven
int pr1;
vector uv1;
float dist1 = xyzdist(1, @P, pr1, uv1); // 选取 左,右 轨迹曲线
vector tangentu1 = primuv(1, 'tangentu', pr1, uv1);
tangentu1 = normalize(tangentu1);
vector pos1 = primuv(1, 'P', pr1, uv1);
vector side1 = normalize(pos1 - @P);
vector dir1 = cross(tangentu1, side1);// *-1; 机翼右翼轨迹曲线需要乘以 -1 取反
float w1 = fit(dist1, 0, 2, 1, 0)*20;

v@vel += dir1*w1;

运行得到解算效果

  • 待更新 gif

高低频控制的进一步讨论

drawing

通过观察上图的最终计算结果我们可以发现,速度曲线绘制的旋转大形,是DOP 中Gas VEX 代码完成计算的部分,这部分的旋转的形态并没有丰富的细节,并不需要在很高精度的速度场上进行编辑,换句话说,当前的翼尖涡流旋转效果,使用最大分辨率128的速度场,和最大分辨率512的速度场制作旋转信息,驱动的最终流体动态效果,并不会有太大区别。

所以我们建议大家在使用 DOP Control 的时候,尽量使用降采样回读编辑,在 DOP 中使用低精度速度场作流体的大形态,在GPU上使用GPU强大的并行计算能力生成丰富的湍流细节。

  • 持续更新中