We were experiencing a crash and finally reproduced it in editor. If you follow these steps, you should crash on the following line in the check in GPUSkinCache.cpp:
1) Open a CO Instance file in Mutable. Make sure one skeletal mesh with LODs and cloth is included and visible.
2) In the LOD picker in the viewport, select a lower LOD (2-3).
3) In Character, check on ‘Enable Cloth Simulation.’
4) Switch to a higher LOD (I was testing going from LOD 2 to LOD 1).
5) In Character, check off ‘Enable Cloth Simulation.’
This causes the crash.
In our game, I believe this manifests because at high player speeds, we disable cloth simulation using the Suspend Clothing Simulation BP node. For a single player, this works fine. We can only repro this crash in multiplayer environments, so most likely the same situation reproduced above occurs when a player triggers this BP node at a distance from the viewing player that also adjusts LODs.
We’re looking into fixing the code but wanted to reach out and see if y’all had any suggestions. Thank you!
One option for this, in SkeletalRenderGPUSkin.cpp, is to to add the following code before the skin cache process entry.
if (ClothSimulationData !\= nullptr)
{
if (ClothSimulationData\-\>LODIndex !\= LODIndex)
{
bSectionUsingSkinCache \= false;
}
}
That seems to skip the GPU skin cache and update via CPU vertex buffer update. Testing looks ok, since the difference usually only lasts one frame until the sim data is updated. This is not the ideal fix, but it works for our situation. I want to investigate further how sim data and mesh data can have some sort of dependency, so the gpu skin cache knows it has to wait for simdata to update.
This looks like it could be a bug on how Mutable generates the LOD transition data. Just to be sure, could you confirm this does not happen with a clothing asset that has not been generated using Mutable?
This ended up crashing in gameplay, so I took another stab at the code. The solution below is much better and does not crash in mutable or in game. SkeletalRenderGPUSkin.cpp.
// Decide to remove the entry if an lod mismatch while processing sections
bool bRemoveEntryFromCache = false;
// inside the section loop
if (ClothSimulationData !\= nullptr)
{
if (ClothSimulationData\-\>LODIndex !\= LODIndex)
{
bRemoveEntryFromCache \= true;
}
}
// after looping over all sections
if (bRemoveEntryFromCache)
{
#if RHI_RAYTRACING
if (Mode \=\= EGPUSkinCacheEntryMode::Raster)
#endif
{
if (SkinCacheEntry)
{
FGPUSkinCache::Release(SkinCacheEntry);
}
}
This removes the skin cache entry for a frame, so the vertex buffer is not updated while lods are mismatched. I also commented out the LOD mismatches in the GPUSkinCache.cpp