World Partition启动PIE很慢

Hi,

我们想了解在WP场景下,有什么好的方式可以优化PIE的启动速度么? 场景大了以后(场景中大概有10几万个Static Mesh),点击Play可能要等待1分钟,甚至更长时间。

这对美术和策划同学的迭代造成了很大的困扰。

[Image Removed]

我们测试了一下,比较极限的拆分Runtime Data Layer,只加载有限的数据层就可以在几秒内启动。但是这样似乎并不符合DL的设计原则。 比如美术同学特别希望能细粒度的加载一小块数据层 然后直接运行起来看效果。感觉DL明显不是为这种思路设计的。

我对DL的理解:

DL主要是分三种:

EDL(Editor DL)

PDL(Private DL)

Runtime DL

PDL和EDL是给美术作为纯粹的关卡资产分类管理的标签来用。

没有任何加卸载逻辑和Gameplay逻辑

大概类似这样的结构

(POI区域名)

POI_A区室外

POI\_A区室外结构

POI\_A区室外道具

POI_A区室内

POI\_A区室内结构

POI\_A区室内道具

大概这样

RuntimeDL用来做某个区域的 由程序逻辑控制的(非自动的)加卸载

以及各种Gameplay相关的功能性区分。

能用PDL的情况,就避免使用EDL。因为EDL可能会产生恶心的引用链问题。 如果保证没有地图复制导致的引用链问题 EDL也是可以用的。

但是用的话也是按照PDL一样的逻辑 就是纯粹用来给美术做资产分区管理

引用链问题具体是指:

如果美术会拷贝地图,那么就可能产生引用链问题。比如一张图做另一种风格,修改,或者个人备份。DL不是私有的会跟地图有引用,美术拷贝地图会导致引用验证连锁反应,可能导致每个地图每张地图十几万的资产引用。到版本控制的时候就爆炸了。。PDL可以有效的规避这种问题。

以上是我对DL的理解。

感觉DL主要是按业务去划分的,如果按照上述的方式去划分DL的话,确实不满足美术同学要求的那种小碎块加载,然后直接运行看效果。 就有点类似WP这个只加载一小块区域 只是WP这个它不影响游戏运行时 只影响编辑器操作

[Image Removed]另外原则上感觉很多东西都不需要放到数据层里面,只需要勾选Is Spatially Loaded就行了。这在游戏打包以后是没什么问题的,但是在编辑器下就非常的慢。

不知道我对DL的理解是否有问题 同时也想请问下 官方是否有推荐的DL使用方式? 其他的就是关于改善PIE的速度是否有什么建议。

关于我提到的美术同学特别希望能细粒度的加载一小块数据层 然后直接运行起来看效果。

这个需求 我个人猜想的一个思路是:

写一个能把世界书签翻译成游戏运行时载入数据层的东西,然后他们会很稀碎的拆数据层 然后做成各种书签选择书签直接启动。反正RuntimeDL拆的再碎 打包之后也没什么影响。所以感觉原则上是可行的。 不知道Epic在这方面是否有计划改善PIE之类的。

Insights也抓了一帧,做为补充:

https://drive.google.com/file/d/1QNFvL0kt3SSQqWlwnlqsqJI9dqA-n-qX/view?usp=sharing

您好,从trace看时间都卡在了FlushAsyncLoading上,看起来应该是描述的​10几万个Static Mesh上,你们项目中远处的建筑植被等细节是否有做HLOD合并吗?

还有个DataLayer的疑问,想请教一下。场景中的模型放在PDL或者EDL里面,和放在RuntimeDL里面有区别么? 我们目前是很多模型是放在RuntimeDL里面的,有的RuntimeDL里面能有几万个Mesh。

放到PDL里面或者EDL里面,他会根据WP的规则加载。 个人感觉放在PDL或者EDL里面和不设置数据层 只勾选Is Spatially Loaded好像没什么区别,唯一区别可能就是放在DL里面 可以充当资产分类管理的标签。不知道我理解的是否正确?

RuntimeDL说是手动管理,但好像也会被WP自动管理的,就算DL设置为active,保留Is Spatially Loaded = true 他依旧走正常WP自动加载。所以感觉上场景的模型放在Editor Layer和放在Runtime Layer好像没什么区别呢?

我们尝试把一部分模型的RuntimeDL配置项删了 不放在DL里面 发现对PIE的启动速度也没什么影响。还是很慢。:sweat_smile:

[Image Removed]

Hi,

我尝试用GetAllActorsOfClass打印场景中的Actor,发现左下角显示加载了2000个Actor左右。

[Image Removed]但是打印出来发现有几万个

[Image Removed]感觉像是WP的加载失效了一样呢,这一般会是什么原因造成的呢?有什么Debug方式么?

而且我发现,就是当我按~切出去以后,在OutLine部分,拖拽一下进度条,左下角的数量也变了。像是WP完全失效了,完全加载了所有东西。

https://drive.google.com/file/d/10s5koH8izivh5MukJgySPeMZqmfc48W6/view?usp=sharing

WP的设置,感觉好像也没什么问题吧。

[Image Removed]

更新一下:

感觉上好像和FastGeo有点关系,我之前测试时候把FastGeo的Transformer删了,但是FastGeo用到的一些cvar没有关掉。不知道是不是这个原因造成的。

我把FastGeo添加回来,再拖动OutLine进度条的时候,就没有出现几万个的情况了。但拖动以后,可以看到左下角的Load数量还是有增加。 我录了个视频:

https://drive.google.com/file/d/1YxYV8PJRBGY\_1pWOSrK1TsCYB2HUqrRm/view?usp\=sharing

然后GetAllActorsOfClass打印出来的,似乎也是拖动以后的Actor数量,最开始Load的数量显示的是2000多,拖动以后是3000多。GetAllActorsOfClass打印出来的也是3000多。我附件里面放了相关的Log。

不知道这个拖动OutLine就会增加到底是什么原因,是否有什么Debug的方式。:sweat_smile:

:sweat_smile: 不好意思,最后请教一个问题,我们发现某些地图,地图尺寸变的不正常了。可能这个也是影响PIE的因素之一。。想了解下这个一般会是什么原因造成的呢?感觉像是Bounds之类的?这种有什么比较好的Debug方式么。

[Image Removed]

Hi,

目前HLOD部分是加了一个基础的Instancing。没有做进一步的合并。

[Image Removed]不知道问题是不是出在DL上,目前我们是为了满足美术同学要求的那种加载一个小区域,可以直接运行起来看效果。所以把每个不同的区域划分到了一个Runtime DL里,这样美术可以通过开关DL,直接测试对应的区域。 但是感觉这样似乎并不合理。

[Image Removed]如果我们只加载很少量的DL,那么PIE速度会很快。但是这意味着我们需要把区域切的更碎。才能满足美术加载一小块,直接预览的需求。我们自己感觉这样的DL用法应该是不对的。

所以想请教下,是否有什么合理的划分DL的方式。 另外就是针对这种小碎块加载,是否有什么思路实现,我在上面的提问中,提到了我自己的设想。

Private Data Layer不依赖datalayer资产、仅存在于关卡内部,是5.1之前旧版的形式,范围局限于当前关卡,无法跨地图共享

Editor Data Layer适用于关卡设计阶段的组织和管理,可以在场景中将美术装饰元素和游戏逻辑相关Actor分开放入不同的编辑器数据层,帮助开发团队分工和优化编辑体验。Editor Data Layer本身并不在游戏运行时生效。

如果你们想影响运行游戏的加载需要使用Runtime Data Layer,这三种datalayer内的actor勾选IsSpatiallyLoaded后都会受到WP的流式加载的影响

只不过目前的问题是一个RuntimeDL里面能有几万个Mesh,这些内容可能没有按照actor的类型和密度分配不同的loadingRange,可以使用多级Grid来让小型植被使用小范围加载网格,地形使用大范围的加载网格,来控制加载对象的整体数量

1.PDL好像是5.3添加的,应该不是历史遗留吧。

2.这个理解了。

3.因为需要快速启动的需求(美术可以加载任意一个区域DL,直接在PIE下运行),所以我们是在一个RuntimeDL里面有几万个Mesh,游戏运行以后,不会加载那么多。运行以后,场景里面只有几千个Mesh。

只是在编辑器下,这个RuntimeDL里面存放了这么多模型。 这样也会影响PIE启动的速度么?

4.是否有更建议的DL划分方式呢?

5.关于前面提到的那种方便开发阶段用的PIE模式(只加载一部分范围 然后运行),是否有什么建议呢?现在等于再拿游戏运行时逻辑去给PIE环境托底,导致开发阶段PIE的速度异常的慢。Epic是否有针对这方面的改进方向呢?

运行后场景只有几千个mesh那是先把那些actor加载进来再通过fast geo合并后的结果吧,现在要解决的是actor加载数量的问题,看看能不能将场景中的大量静态mesh合并为少量的PackedLevelActor,在运行前就控制住actor的数量​。

对于​要测试只加载一部分范围的效果,我觉得你们把这部分区域做成一个level instance,在一个空场景通过datalayer控制加载想要的level instance

运行后只有几千,原则上来说,应该是WP的加载范围影响的吧?

fast geo,我只添加了一个Actor。他是自己有合并相关的操作么?另外他可以和WorldPartitionRuntimeCellTransformerlSM一起用么?

Package Level Actor这个,我们试试看。

CellTransformer只能选一种,fastgeo的transformer我估计你们没生效,需要打开一些异步cavr但是5.6上一些安全问题引擎默认是关闭的,应该会报类似这种错误:

LogFastGeoStreaming: Error: FastGeoStreaming Cell Transformer requires ‘p.Chaos.EnableAsyncInitBody’ to be enabled.

你们可以先用WorldPartitionRuntimeCellTransformerlSM

1.我理解的运行后,只有几千个Mesh,首先应该是WP的加载范围影响的吧?DL里面虽然有几万个Mesh,但因为加载范围的限制,应该不会全部都载入一遍吧,应该是按加载范围加载一遍,然后再走fast geo?

2.p.Chaos.EnableAsyncInitBody这个我们一直是打开的,当时是看了City Sample。直接把cvar拷贝了。FastGeo里面是只添加了Actor,不知道还要不要添加别的。

[Image Removed]

3.FastGeo和WorldPartitionRuntimeCellTransformerlSM只能二选一么? 我看官方指南里提到可以和多个Cell Transformers一起使用。

“It leverages the World Partition - Runtime Cell Transformer feature to define what can be considered for fast geometry streaming during the streaming generation phase that happens every time entering Play in Editor (PIE) and at Cook time. This makes the process seamless and non-destructive. It can also be layered with multiple Cell Transformers for further improvements.”

https://dev.epicgames.com/community/learning/knowledge-base/r6wl/unreal-engine-world-building-guide#wp-importantchangesin56

1. 是的,但如果cell设置的loadingrange范围很大,mesh很多又很近还是会加载进来

2.这个cvar更改成功后在pie下运行看看有没有报错,场景中的actor是否都被合并了,是的话应该就没问题

3.可以配置多个Cell Transformers并行处理,但一个里面只能填一个

1.明白了,感谢。

2.这个合并有什么明显的方式能观察到么?我在空场景里,做了个测试。FastGeo设置了一个Actor。

[Image Removed]运行的时候,OutLine里面是看不到这几个模型的。F8切出去也无法选中。

[Image Removed]不知道是否有什么更直观的方式去观察它是否合并成功了。 Log里面是没有报错的。

3.那么我是否可以比如FastGeo里面配置了一个Actor,然后WorldPartitionRuntimeCellTransformerlSM设置PartitionActor和StaticMeshActor之类的。 不是很理解这个一个里面填一个的含义。

比如这样:

[Image Removed]FastGeo设置Actor:

[Image Removed]WorldPartitionRuntimeCellTransformerlSM设置这些:

[Image Removed]

2.说明合并成功了,因为合并成功的那个actor不是在编辑器下编辑的,所以看不到

3.WorldPartitionRuntimeCellTransformerlSM的作用就是在levelstreaming的时候遍历每个cell的所有填的allowedClass的actor取得里面的staticmeshComp合并到一个AWorldPartitionAutoInstancedActor里面,并且把之前的那些actor都删掉,就保留这一个

你试下把celltransformer关掉,看看不合并场景是多少actor来着

在编辑器下没有开启asyncloading thread,所以PIE下的加载都在主线程上,可以强行打开Editor的异步加载线程,但是可能存在安全问题,如果你们感兴趣可以在DefaultEngine.ini中试下,我本地测了下是有效果的

​[/Script/Engine.EditorStreamingSettings]

s.AsyncLoadingThreadEnabled=true

s.AsyncPostLoadEnabled=True

1.WorldPartitionRuntimeCellTransformerlSM的作用就是在levelstreaming的时候遍历每个cell的所有填的allowedClass的actor取得里面的staticmeshComp合并到一个AWorldPartitionAutoInstancedActor里面,并且把之前的那些actor都删掉,就保留这一个

那么这样看的话,按照我上面的配置Fast Geo和WorldPartitionRuntimeCellTransformerlSM,似乎就有冲突了? FastGeo直接把Actor都合了,WorldPartitionRuntimeCellTransformerlSM就没什么干的了。 那么文档中提到的多个Cell Transformers的最佳实践应该是怎样的呢?

2.在测试场景里面测试,把两个celltransformer都关掉,场景里面的Actor是77,开了以后是63。开了以后,那几个测试的Mesh就消失了。WorldPartitionRuntimeCellTransformerlSM就完全没有发生作用了。

3.asyncloading thread这个,我们测试一下,感谢。

4.关于前面提到的PackedLevelActor,想请问下,它和ISM有什么本质上的区别么?ISM也可以多个不同的Mesh组合在一起,感觉和PLA功能上都差不多。这两者有什么本质上的区别么?一般情况下,我们用合并ISM比较多,不知道PackedLevelActor对比ISM,到底有什么区别,这方面一直挺疑惑的。

fastgeo的transformer和ism的作用不太一样,它是用于收集所支持的类型的actor/comp,批量注册和异步,目前支持的类型有这些

[Image Removed]我的理解你可以先用ism转成少量AWorldPartitionAutoInstancedActor,再用fastgeo统一注册,这个功能目前还比较前期还没有最佳实践文档可供参考

PackedLevelActor我的理解它是用于编辑时,transformerism的作用时机用于pie的generate streaming和cook时,其次是transformer不会影响源内容。

你们主场景在pie进入卡一分钟,在使用transformer前后actor数量差距大吗

1.感谢分享。后来我们看了一下,这里是有先后顺序的。这个stack就是个tarray,它就只是按照array的index顺序跑,所以要先配置ism再fastgeo才行。

反过来配置以后,就会先ism,再fastgeo了。fastgeo的处理可以包含ism。

[Image Removed]

2.PackedLevelActor用于编辑时,这个怎么理解呢? 主要感觉ISM和PLA似乎没什么区别,ISM也可以多个Mesh合在一起,组成一个Actor,并且ISM的组合和拆解相对容易,完全没感觉到PLA的优势在哪里。 这两个在使用上有什么区分么?感觉Epic比较推荐的还是用PLA 而非ISM。 这两个太像了,有点迷惑。

3.我们是只用了fast geo,设置了Actor。有时候差距还是很大的。但有时候又没什么差距。不知道为什么,每次Play的时候,加载的Actor都是浮动的。

PIE的时候,都是同一个位置。

这里有两张图,可以看到有时候,PIE的时候加载了1000多,有时候加载了2000多。 这是开了FastGeo的。

[Image Removed]

后面我们测试了一下,发现好像没有FastGeo,在加载的时候也浮动很大。有时候有1-200的浮动,有时候1000+的浮动。

[Image Removed]不知道这是什么原因造成的,我们录了一个视频,可以看到每次PIE的时候,加载的Actor都浮动挺大的。

https://drive.google.com/file/d/1DUKhk_KBffpsNwNFlgUCJ5S0_H1lhega/view?usp=sharing

这个有什么方式调查原因么?另外有什么比较好的方式可以在PIE的时候把OutLine的列表Dump出来么?

而且OutLine这个是不是有什么问题呢?有时候在PIE下,想看看OutLine实际的东西,发现滚动一下或者拖拽一下进度条,左下角的数量就变了。

https://drive.google.com/file/d/10s5koH8izivh5MukJgySPeMZqmfc48W6/view?usp=sharing