Unreal Engine*:制定布料模拟 CPU 优化蓝图

布料模拟

逼真的布料运动可大幅提升游戏的视觉沉浸感。我们可以使用 PhysX Clothing 实现这一目标,无需手工绘制动画。将这些模拟整合到 Unreal Engine* 4 中非常容易,但该流程需占用较多 CPU,因此最好了解模拟的性能特征及优化方式。

禁用布料模拟

在 Unreal* 中,布料模拟位于相应的关卡,无论是否可见。优化可防止该风险。优化模拟布料时请勿依赖 Disable Cloth 设置,因此它仅在构建中有用,在游戏进行时毫无用处。

Unreal Physics 统计s

为更好了解布料模拟及其对游戏和系统的影响,我们可在 Unreal 中使用控制台命令 Stat PHYSICS。

在命令行中输入 Stat PHYSICS,然后会出现物理结构表覆盖(图 1)。删除它请在控制台中输入相同命令。

Physics overlay table
图 1.物理结构覆盖表。

尽管有大量信息可用,但我们还存在两方面(Cloth Total 和 Cloth Sim)担忧。

Cloth Total 表示场景中的布料绘制总数,Cloth Sim(模拟)表示当前模拟的活跃布料网格数量。确保这两个数目处于目标平台的合理水平内,有助于防止处理布料造成 CPU 过载和帧速下降。通过在该水平中添加更多布料网格,CPU 一次可处理的模拟数量便显而易见。

暂停布料模拟

Unreal Engine 蓝图系统还具备另外一项功能,即在骨架网格上暂停和恢复布料模拟。这些增加的节点可解决之前使用布料优化的细节级别方法时,每次都需要重置布料模拟的问题。

Rendered function switch
图 2.was recently rendered 功能转换的恢复和暂停。

出于本文的目的,“细节级别”部分所探讨的所有方法都适用,但现在可以将 Set Min LOD 节点和 Resume and Suspend Clothing Simulation 节点进行互换。

时间延迟转换

通过暂停布料模拟,我们可以增加布料的动态性同时优化性能。然而,仅使用遮挡转换可能会导致出现旗帜降落问题;其中布料模拟中包含动态移动,玩家走开(暂停布料模拟),一段时间后回来继续移动之前看到布料模拟在半空中飘扬。

为了解决这一问题,我们可以使用遮挡转换并添加一个布尔值来查看暂停;使用这种方法时可以在暂停模拟之前可以使用延迟,这样在最终停止之前布料有充足的时间完成移动并保持暂停。

Time delay switch
图 3.Time delay switch.

细节级别

在创建骨架网格并在其中附加一个顶点布料文件时,布料模拟将始终与该网格细节级别 (LOD) 的零值关联。如果网格的 LOD 0 被禁用,布料模拟将不再发生。为发挥其作用,我们可创建与 LOD 0 完全相同的 LOD 1(减去布料顶点文件),并将其用作转换,无论是否使用布料模拟(图 4)。

Level of detail information
图 4.细节级别信息。

布尔转换

既然已有转换,我们可设置简单的蓝图控制它。通过创建事件(或函数),我们可在模拟布料 (LOD 0) 和不模拟布料之间使用布尔转换,实施分支。该事件可在输入的触发器上调用,以开始在下一个区域模拟布料网格,并在玩家离开该区域时再次调用,以停止模拟或任何数量的方法,取决于游戏关卡。

Occlusion Culling Switch
图 5.转换蓝图。

遮挡剔除转换

如果希望采用更自动化的方法,可将遮挡剔除用作交换变量。为此,调用Was Recently Rendered函数,并返回转换分支(图 6)。这会在对象不再被渲染时阻止布料模拟。

Recently Rendered function in the switch blueprint.
图 6.转换蓝图中的”Was Recently Rendered”函数。

该方法的问题在于模拟恢复启动时发生的模拟重置。如果布料网格与模拟时显著不同,玩家将始终看到这种转换。为降低这种情况发生的概率,可通过导入设置扩大网格边界。然而,这也意味着故意渲染玩家看不到的对象,因此请确保其有助于满足游戏的渲染需求。

解决此问题的一个关卡设计方法包括确保所有动态布料网格(如旗帜)与风处于同一个方向。

我们可以使用 C++ 设计一种方法,以保存布料模拟每个顶点的位置数据,并在模拟恢复启动时恢复网格的位置。这种方法会占用较多资源,具体取决于使用的数据结构以及关卡中的布料模拟数量。

Cloth simulations without occlusion culling switch
图 7.未使用遮挡剔除转换的布料模拟。

Cloth simulations with occlusion culling switch.
图 8.使用遮挡剔除转换的布料模拟。

组合/Set Piece 转换

如果关卡碰巧具有一个极易变化且始终非常重要的 set piece,可在对象中附加一个使用布尔转换的额外分支。如图 9 所示,我们将其称为Optimize Cloth?

Set piece switch.
图 9.Set Piece 转换。

使用这种新转换时,某些布料网格非常重要,应始终通过将其Optimize Cloth?值切换至 false 进行模拟。

使用 Set Piece 转换

在下面的图 10 中,三个布料网格为转向朝后的旗帜(相对于起始位置)。需要数秒时间呈现自然状态,但由于它们确实并非手工绘制动画,因此我将它们设置为 Set Pieces(Optimize Cloth? false),它们可始终被模拟。

Complex flags used with set piece switches.
图 10.使用了 set piece 转换的复杂旗帜。

有关编译器优化的更完整信息,请参阅优化通知