void USsPlayerComponent::SendRenderDynamicData_Concurrent()
{
	if(NULL == SceneProxy)
	{
		return;
	}

	switch(RenderMode)
	{
		case ESsPlayerComponentRenderMode::Default:
			{
				const TArray<FSsRenderPart> RenderParts = Player.GetRenderParts();
				TArray<FSsRenderPartWithMaterial> NewRenderParts;
				NewRenderParts.Reserve(RenderParts.Num());
				for(int32 i = 0; i < RenderParts.Num(); ++i)
				{
					FSsRenderPartWithMaterial Part;
					FMemory::Memcpy(&Part, &(RenderParts[i]), sizeof(FSsRenderPart));

					uint32 MatIdx = PartsMatIndex(Part.AlphaBlendType, Part.ColorBlendType);
					UMaterialInstanceDynamic** ppMID = PartsMIDMap[MatIdx].Find(Part.Texture);
					if(ppMID && *ppMID)
					{
						Part.Material = *ppMID;
					}
					else
					{
						UMaterialInstanceDynamic* NewMID = UMaterialInstanceDynamic::Create(BasePartsMaterials[MatIdx], this);
						if(NewMID)
						{
							NewMID->AddToRoot();
							NewMID->SetFlags(RF_Transient);
							NewMID->SetTextureParameterValue(FName(TEXT("SsCellTexture")), Part.Texture);
							
							Part.Material = NewMID;
							PartsMIDMap[MatIdx].Add(Part.Texture, NewMID);
						}
					}
					NewRenderParts.Add(Part);
				}

				if(0 < NewRenderParts.Num())
				{
					ENQUEUE_UNIQUE_RENDER_COMMAND_FOURPARAMETER(
						FSendSsPartsData,
						FSsRenderPartsProxy*, SsPartsProxy, (FSsRenderPartsProxy*)SceneProxy,
						TArray<FSsRenderPartWithMaterial>, InRenderParts, NewRenderParts,
						FVector2D, Pivot, Player.GetAnimPivot(),
						FVector2D, CanvasSizeUU, (Player.GetAnimCanvasSize() * UUPerPixel),
					{
						SsPartsProxy->CanvasSizeUU = CanvasSizeUU;
						SsPartsProxy->SetPivot(Pivot);
						SsPartsProxy->SetDynamicData_RenderThread(InRenderParts);
					});
				}