[Deformer Graph] Advanced Seleton node: buffer overflow when the LOD level changes

When changing LOD level, there are some left over jobs/call to:

// D:\UnrealEngine\Engine\Plugins\Animation\DeformerGraph\Source\OptimusCore\Private\DataInterfaces\OptimusDataInterfaceAdvancedSkeleton.cpp void FOptimusAdvancedSkeletonDataProviderProxy::AllocateResources(FRDGBuilder& GraphBuilder, FAllocationData const& InAllocationData){ ... // on LOD transition InvocationIndex >= AttributeBuffers.Num() BuffersPerAttributePerSection[InvocationIndex].AddDefaulted(AttributeBuffers[InvocationIndex].Num()); ...And because AttributeBuffers size does not reflect the current LOD level anymore it triggers a segfault/buffer overflow.

Proposed fix:

The fix I found is simple, FOptimusAdvancedSkeletonDataProviderProxy::IsValid() should check that AttributeBuffers is still correct:

FOptimusAdvancedSkeletonDataProviderProxy::IsValid(){ ... // this should probably be added: if (AttributeBuffers.Num() != LodRenderData->RenderSections.Num()) { return false; }This way, AllocateRessources won’t be called on buffer outdated buffer size, and a call to UOptimusAdvancedSkeletonDataProvider::GetRenderProxy() will be triggered to update buffers according to the current LOD level.

Cheers!

Actually my fix is not so good, it will prevent buffer overflow but now triggers flickering / jumps in the deformation (see video).

Steps to Reproduce
I could confirm it on 5.5 and main.

Assign a LBS deformer asset to some skeletal mesh. (the deformer needs to use Advanced Skeleton node)

Make sure the skel mesh has at least 2 LODs.

LOD1 should be composed of less mesh sections than LOD0. (LOD0_mesh_section_num > LOD1_mesh_section_num)

Load a map with the skel mesh from afar: so that LOD1 is loaded first.

Get closer to the model to trigger a change to LOD0.

Buffer overflow will happen on LOD transition.

For sake of completeness here is the model I have used (“shinbi__sns_skin_weights.fbx” is used as skin weight profile for “shinbi_base_lodel.fbx”) 3 LOD were auto generated.

Here is a brute force fix of OptimusDataInterfaceAdvancedSkeleton.cpp/h where AttributeBufferOffsets is stored and updated for every LODs.

This way flickering stops happening, obviously there must be a better way to achieve this.

Hi! Thank you so much for the detailed report on this issue, I will take a look at it and get back to you as soon as I can.

Jack

Just an update, I am still investigating the issue but will be traveling next week. Will resume work once I get back.

Jack

Managed to repro locally, will update as soon as I find a fix

Jack

I submitted a fix for this to 5.6 stream, CL 42402131, could you give it a try and let me know?

You are absolutely right with your diagnosis. It was a bad idea to create LOD specific buffer during GetRenderProxy() since the LODIndex can be updated after the proxy is created. To fix the issue, we have moved the construction of LOD specific buffers to AllocateResources(). Hope this CL addresses the issue for you. Thank you once again for the test assets and detailed report!!

Jack

Thank you so much I finally had time to integrate your fix in 5.5 and it fixed this particular issue :folded_hands: