物理场示例提供的写法存在问题

Hi,

我们最近在测试物理场的时候发现,引擎中提供的示例写法似乎不正确。引擎示例中的写法会导致每帧都在创建组件,这一点可以通过打印出来这个Actor的组件数量发现。

[Image Removed]

引擎内的示例都存在这种问题。

[Image Removed]

主要问题似乎来源于各种Add XXX方法,这些方法其实是组件创建的方法,在Tick中使用,会导致每帧都在创建组件。官方这么写应该没办法用吧,运行一会,一个actor得有几万个组件。

这个问题,有什么好的修复建议么?

我们目前解决办法是手动创建各种所需的场和操作符,避免在运行时创建任何东西。。还是挺麻烦的。:sweat_smile:

[Attachment Removed]

您好, 抱歉回复晚了.

确实有这个问题, FS_MasterField想演示各种形状各种operator如何操作, 但又不想为每种情况预先创建, 所以使用了Add Component. Niagara文件夹下的这些每tick都作用的场确实更适合预创建Component, 我也会和开发沟通下要不要修改下示例.

请问用预创建的制作方式目前遇到的主要麻烦是?

[Attachment Removed]

从stat里看, 主要的瓶颈可能是布料的点数, 除了[Field Update] LinearForce, 几个PBD约束求解的开销同样很高. 这些都是和布料点数直接相关的, 而且物理场在布料上的的linear force更新没有ISPC路径, 循环布料每个点更新力, 这部分开销比较突出, 当然也受场本身的计算复杂度影响.

我觉得这里可以先从布料的优化入手, 一般建议布料的渲染和解算模型拆分开, 控制解算模型的点数并设置LOD. 如你所说, 用proxy流程. 可以参考一下这个分享. Panel cloth也可以用于场景布料, 甚至这方面比旧的系统更方便, 不一定要和skeletal mesh绑定, 但两种流程底层布料算法差别不大, 资产方面的优化手段也是一致的. 另外, 如果布料覆盖范围内, 局部的受力方向变化不大, 建议不要用Point Based Wind Model, 用panel cloth的aerodynamics风力模型, 运行时, 在布料的pivot计算一次风向后, 通过Cloth Interactor调整风向, 如下. 这样一方面不需要逐点的计算场的方向, 另一方面这种空气动力学的模型布料调整lift&drag后在风中抖动翻飞的效果也更真实, 可能也没必要叠加Noise场. [Image Removed]

现在的示例物理场我没有发现明显问题, 如果方向每帧都在变化的话, persistent field确实不适用, 我不知道效果上是否允许, 但可以考虑参考fs_MasterField, 给场加一个lifespan, 一段时间后销毁或停止add transient field这样.

[Attachment Removed]

老师,我看到UE-377966有更新了。显示的By Design。这个是指不会修改么?

在Tick每帧都增加组件,这种东西不改,给开发者当示例还符合设计么。:sweat_smile:

[Attachment Removed]

:sweat_smile: 主要麻烦还是来自制作人员,他们会直接照搬官方的Field演示,直到我们Debug发现有性能瓶颈的时候,才注意到。不同项目组,都会多多少少遇到类似的情况。所以感觉还是官方有一个规范点的演示,更好一些。

[Attachment Removed]

了解, 我创建了一个bug单(UE-377966), 后面有修复会回复在这里.

目前还要麻烦项目组同事修改下Engine Content, 把继承自FS_BaseField的这几个示例改为预创建component, 功能上不会有差别的. 此外还有FS_MasterField, 因为演示功能比较全, 建议实际项目中作为参考, 不要直接以On Tick的激活模式使用.

[Attachment Removed]

好的,感谢老师。

[Attachment Removed]

老师您好,再请教个问题。

我们想用物理场构建一个风场,基于前面说的,做了预创建,但是感觉性能开销还是很大。能麻烦老师帮忙看一下还有哪些优化的点么?

其中一个 是我们感觉这个Field似乎不应该放在Tick内,但是好像也没什么其他地方可以放。 关于物理场的资料有点少。找不到太多参考。

[Image Removed]在这里有两个BP,一个是没有预创建的,一个是改了预创建的。希望老师能提供一些改进的意见。

[Image Removed]工程放在附件中了。

[Attachment Removed]

想再问一下​现在测下来实际场景中具体哪部分性能开销比较大? 是Stat Chaos里的field system update相关的几条么?

对这种一直或一段时间存在的field, 建议尽量少在tick里持续add transient field, 可以先看看能不能用persistent field代替, 这样不需要每帧Dispatch任务, BeginPlay或者事件触发, 不用的时候Remove Persistent Field就好了. ​ [Image Removed]

刚体应用物理场的开销随刚体数量增长, 需要注意Field Resolution的设置, 你可以参考一下​FS_MasterField中FieldSystemMetaDataResolution的设置, 尽量用Minimum, 也就是只施加给物理模拟中的激活的粒子, 少用Maximum(全部刚体).

[Image Removed]

物理场在GPU上的优化主要需要注意写出的clipmap的精度和范围:

r.PhysicsField.ClipmapCount

r.PhysicsField.ClipmapDistance

r.PhysicsField.ClipmapResolution

r.PhysicsField.SingleTarget (1, 只写出linear force)

另外, 附一些物理场相关的教程和分享:

Physics Field Doc

Chaos Destruction Tut - Field

《UE中的世界物理场及应用》 | 李文磊 Epic

物理场在Niagara中驱动流体

[Attachment Removed]

老师您好,

目前测试下来确实是和field system update相关的,还有的看起来可能和布料相关。

[Image Removed]关于Field部分,因为做的是风场,需要运行时变化风向之类的。感觉add transient field好像不太能替换成persistent field吧?用persistent field风场似乎就没效果了。这部分不是特别清楚。用add transient field的话,确实感觉每帧Tick有点怪,但是没想到什么其他的思路。。

刚体这部分确实是没有注意到,FieldSystemMetaDataResolution这个我们会加上测试一下。

另外也想请老师帮忙看一下我们上面发的那个例子,有没有比较明显的错误做法。因为考虑到扰动之类的,里面是加了两个add transient field,感觉这种似乎不太好。

还有一个问题就是关于布料部分,新的panel cloth似乎是只针对于角色布料的,对于场景中的一些布料做随风场运动之类的,这个系统好像并不支持。只能使用旧的布料系统,旧的布料系统在解算方面好像十分耗费性能,即使是一个几千面的模型,在解算上开销也不低。何况需要在场景中摆放一定数量呢。

我们想了解在这方面有什么比较建议做场景布料的方式么。目前感觉能想到的就是要么在场景解算布料上,也是再做一个Proxy Mesh绑定上,用更低面数的模型做解算。 或者就是材质WPO之类的,然后采样物理场?

[Attachment Removed]

感谢老师,我看了一下旧的布料系统好像默认就是用的aerodynamics风力模型。不过后面您贴的这个蓝图,应该是panel cloth才能使用的吧。

我还没有去看场景布料应该怎么使用这套系统,后面研究一下。目前已有的资料,好像都是讲角色布料的。

关于add transient field这个部分,感谢老师的建议,我会去看看fs_MasterField的实现。

persistent field感觉好像并不适用于风场,毕竟风场可能随时需要变化风的方向速度之类的。

[Attachment Removed]

是的, 旧的系统默认是aerodynamics, 也可以从蓝图里设置风向, 接口不同, 如下:

[Image Removed]如果不是角色布料的话, panel cloth可以直接读static mesh创建布料, 然后通过chaos cloth component放置在场景中.

[Attachment Removed]

明白了,感谢老师。这部分应该就可以在BeginPlay,或者在自定义事件里面调用就可以吧。

panel cloth这部分理解了,感谢老师。

[Attachment Removed]

是的, 事件或动画蓝图里调用都可~

有问题再沟通!

[Attachment Removed]

明白了,还有一个问题请教。就是如果用上面蓝图采样物理场的方式去驱动布料。那么我应该需要消除物理场原本对布料的影响吧?

我理解的是用Meta Data Filter过滤掉。但是有个问题,在上面您提到需要设置FieldSystemMetaDataResolution,来减少刚体的开销。

那么好像就没有位置去设置Meta Data Filter了。只能有一个在组件上进行全局设置么? 还是说我理解的有问题。

[Image Removed]

[Attachment Removed]

是的, metadata resolution和metadata filter这两种过滤控制只能选一种, 如果想排除对布料的影响, 我看了下确实只有一种方式, 就是你上面截图的Set Meta Data Filter.

之前有一个地方我搞错了, 引擎早期版本上只有勾选Use Point Based Wind, 物理场才会对布料有影响, 现在是直接调整布料点的速度/受力了, 抱歉造成误导~

[Attachment Removed]

另外补充一点, Set Wind方法里, Wind Velocity只控制方向, 强度可以通过Air Density控制, Drag是方向平行于风和布料相对速度的力, 促使各点速度向风的方向统一, 使动态更稳定, Lift使方向垂直于风和布料相对速度的力, 促使布料在风中翻飞抖动. 如果希望扰动效果强一点, 可以试试把Lift调的比Drag高一些.

[Attachment Removed]

理解了,用蓝图采样物理场控制布料得消除物理场本身的影响,所以感觉metadata filter是必须得设置的。

那么看来只能在metadata resolution和metadata filter上选一个添加到Filed上,另外一个在组件上进行全局设置了。

感觉metadata resolution可以在组件上做全局的设置。filter用来区分不同Field的影响,可能更好一些。

Set Wind部分,感谢老师的补充。

[Attachment Removed]

开发已经确认了这个问题, 但把field资产的优化排到后面版本了, 暂时关闭了这个任务.

没有赶上5.8, 抱歉, 但后面会调整为"only initializes the field (“Add Radial Vector”, “Add Uniform Vector”, etc) once on begin play or construction instead of being called in Event Tick"

[Attachment Removed]

明白了,感谢老师解惑。

[Attachment Removed]