Temporary disable MeshStreaming for asset in runtime

Hi there,

We’ve enabled MeshStreaming for both Static and SkeletalMesh on our project. It’s working and yielding some good memory savings. But, we start to see some Mesh poping happens in our game. More specifically, some of the nearby skeletal meshes will be hidden and then revealed again frequently, every time they got re-render in the scene, they will render as low res mesh then pop the full res that we want.

Opting those meshes out of streaming would be our last resort. So I was wondering if there any way to ‘temporarily’ disable their asset streaming when they are nearby. Or could you point me to some place in the code that will do the job?

Steps to Reproduce

Hi there,

there is no straightforward way to selectively disable mesh streaming on a per instance basis. The mesh popping is probably caused by the fact that streaming isn’t instant and requires some time to load the LOD.

You can try setting Global Force Resident Mip Levels (bForceMiplevelsToBeResident) to true on the skeletal mesh asset when it’s spawned and set it back to false when it gets destroyed. This should reduce popping as it streams in all the LODs and will allow rendering a lower LOD when LOD0 hasn’t loaded yet.

Another option is to enable NeverStream on the mesh asset, but this will essentially disable the streaming mechanism.

There is some more info in the topics below

[Content removed]

[Content removed]

[Content removed] (this topic is in Japanese, but it can be translated to English by right-clicking it when using the Chrome browser)

I hope this helps. Please let me know if you have further questions.

thanks,

Sam

I was able to repro this issue in Vanilla UE. So basically I setup a humanoid (6 LOD generated) mesh in the empty map and SetForceLOD(1), have a trigger cube to hide the mesh or unhide when out. And then set r.Streaming.Poolsize 1 (I have to super aggressive on this cause there only 1 mesh in the mesh)

Try to walk in&out the hidden cube and oberse mesh I can see the mesh pop.

Hi, thank you for getting back. I don’t think there is a setting to prevent the mesh streaming system from streaming out non-visible meshes without disabling streaming entirely. There may be a few ways to work around it however, if using “Never Stream” is not an option:

  • you can apply a fully transparent material to the mesh (set blend mode to translucent and set opacity to 0). This will keep the skeletal mesh in the scene and allow streaming to still work, however making it transparent comes with a significant shading cost
  • instead of making the mesh transparent, another option is to reduce the scale of the mesh to something very small such that it becomes invisible. Since the mesh is still part of the scene, LOD selection and mesh streaming should still work, and the shader cost should be close to zero as it doesn’t occupy any screen space
  • you can use a combination of applying a fully transparent material and scale reduction to significantly reduce the shader cost

If the above suggestions don’t work, would you be able to share the repro scene?

Thanks,

Sam

That sounds like a good solution, glad to hear that worked for your case.

I will close the ticket, but please feel free to re-open it if you have any further questions.

Thanks,

Sam

Thanks for the reply.

I did some experiments with SetForceLOD(1), and it works pretty well, even pretty aggressive pool memory under budget (In my case: 10mb total) The mesh still keeps the detail. Which kinda of meets our needs; basically, we want all the first-person mesh components to not stream. But we don’t want to disable Mesh Streaming on them entirely, similar to the one of ticket you referenced; those would also use as third person mesh, it’s not worth the full LOD.

But, SetForceLOD(1) still couldn’t resolve the LOD pop when meshes Hidden and display again, they got stream out as they lose the visibility.

I was able to track down to the FAsyncRenderAssetStreamingData::UpdatePerfectWantedMips_Async() where it update the WantedMip (Which I think it probably shouldn’t for ForcedLOD mesh), and inside of DynamicInstancesView.GetRenderAssetScreenSize(), Element wasn’t able to be find thru ElementIterator (guess because it’s not visible in the view)

Anyway, I think I’d narrow my question to: How to prevent a ForceLOD mesh from streamout when not visible?

Thank you for your reply. We ended up using another way to hide the mesh through enqueuing a SetForceHidden to Component’s SceneProxy, and also combine the SetForceLOD(1) at the very beginning of the mesh. In this way, we can keep the visibility of the component while render nothing when needed.