Hi, 我们发现,在子关卡 LoadedVisible->LoadedNotVisible->LoadedVisible 后,子关卡中的 static light 会变成 dynamic。
我们做了初步的排查,定位到原因是:
- static LightComponent 可以作为静态光渲染的条件是,能够从 MapBuildDataRegistry 获取 LightComponentMapBuildData,如果不能获取,就会动态渲染光照。
- 获取 LightComponentMapBuildData 依赖正确的 ULightComponentBase::LightGuid
- 每次 LightComponent AddToWorld,Register 的时候,会重新计算 ULightComponentBase::LightGuid,计算过程依赖了所属 Actor 的 ActorInstanceGuid
- ActorInstanceGuid 是在加载 Actor 序列化的时候被添加到 GActorGuids 里的,当这个 Actor 的所有 Component 完成了 AddToWorld 以后,就会从 GActorGuids 中释放掉。
- 当子关卡 LoadedVisible->LoadedNotVisible->LoadedVisible 时,第二次 LoadedVisible,会重新将 LightComponent AddToWorld,重新计算 LighGuid,但是此时 ActorGuid 已经被释放掉了,导致计算得到的 LightGuid 错误,因此无法获取 LightComponentMapBuildData,因此这个 light 被动态地渲染了,当子关卡中 static light 很多时(几百个),性能会下降。
我们有一个临时的补丁解决:
在第二次将 LightComponent AddToWorld,重新计算 LightGuid 时,如果发现此时 ActorGuid 已经被释放掉了,就不更新 LightGuid,还使用上次的。
但是这只能作为临时的解决方案,不知道与 ActorGuid 系统的设计是否完全吻合,是否会导致其他问题。
[Image Removed]
[Attachment Removed]