Skip to content

Commit

Permalink
Merge pull request #1327 from bdunderscore/merge-blend-shape
Browse files Browse the repository at this point in the history
perf: improve performance of AutoMergeBlendShape
  • Loading branch information
anatawa12 authored Nov 4, 2024
2 parents 43ca9ef + 91598a0 commit dd45e45
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-PRERELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog].

### Changed
- Improved performance in InternalAutoFreezeMeaninglessBlendShapeProcessor [`#1325`](https://github.com/anatawa12/AvatarOptimizer/pull/1325)
- Performance improvements for AutoMergeBlendShape `#1327`

### Deprecated

Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ The format is based on [Keep a Changelog].
- Renamed debug options internally `#1228`
- This will lose previously configured debug options.
- However, debug options are not considered as Public API as stated in documents so this is not backward incompatible changes in semver 2.0.0 section 8.
- Performance Improvements `#1234` `#1243` `#1240` `#1288` `#1304` `#1307` `#1314` `#1325`
- Performance Improvements `#1234` `#1243` `#1240` `#1288` `#1304` `#1307` `#1314` `#1325` `#1327`
- Transform gizmo are now hidden while you're editing box of Remove Mesh in Box `#1259`
- This prevents mistakenly moving the Skinned Mesh Renderer while editing the box.
- Make MergePhysBone implement `INetworkID` `#1260`
Expand Down
28 changes: 25 additions & 3 deletions Editor/Processors/TraceAndOptimize/AutoMergeBlendShape.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.Profiling;

namespace Anatawa12.AvatarOptimizer.Processors.TraceAndOptimizes;

Expand All @@ -23,13 +24,22 @@ protected override void Execute(BuildContext context, TraceAndOptimizeState stat
{
if (state.Exclusions.Contains(skinnedMeshRenderer.gameObject)) continue; // manual exclusion

ErrorReport.WithContextObject(skinnedMeshRenderer, () => DoAutoMerge(context.GetMeshInfoFor(skinnedMeshRenderer), context));
ErrorReport.WithContextObject(skinnedMeshRenderer, () =>
{
Profiler.BeginSample("GetMeshInfoFor", skinnedMeshRenderer);
var meshInfo = context.GetMeshInfoFor(skinnedMeshRenderer);
Profiler.EndSample();

DoAutoMerge(meshInfo, context);
});
}
}

private static void DoAutoMerge(MeshInfo2 meshInfo2, BuildContext context)
{
var animationComponent = context.GetAnimationComponent(meshInfo2.SourceRenderer);

Profiler.BeginSample("Compute merge keys");
var groups = new Dictionary<MergeKey, List<string>>();

foreach (var (name, weight) in meshInfo2.BlendShapes)
Expand All @@ -43,10 +53,17 @@ private static void DoAutoMerge(MeshInfo2 meshInfo2, BuildContext context)
}

// nothing to merge
if (groups.Values.All(x => x.Count <= 1)) return;
if (groups.Values.All(x => x.Count <= 1))
{
Profiler.EndSample();
return;
}
Profiler.EndSample();

Profiler.BeginSample("Prepare merge");
// prepare merge
var buffers = meshInfo2.Vertices.Select(x => x.BlendShapeBuffer).ToArray();
var buffers = meshInfo2.Vertices.Select(x => x.BlendShapeBuffer).Distinct().ToArray();
Profiler.EndSample();

// bulk remove to optimize removing blendshape process
var removeNames = new HashSet<string>();
Expand All @@ -59,6 +76,7 @@ private static void DoAutoMerge(MeshInfo2 meshInfo2, BuildContext context)
{
// validate the blendShapes are simple enough to merge
// if not, skip
Profiler.BeginSample("AutoMergeBlendShape: Validate");
foreach (var buffer in buffers)
{
float? commonFrameWeight = null;
Expand All @@ -80,6 +98,7 @@ private static void DoAutoMerge(MeshInfo2 meshInfo2, BuildContext context)
}
}
}
Profiler.EndSample();

// validation passed, merge
var newName = $"AAO_Merged_{string.Join("_", names)}_{i++}";
Expand All @@ -94,6 +113,7 @@ private static void DoAutoMerge(MeshInfo2 meshInfo2, BuildContext context)
meshInfo2.BlendShapes.Add((newName, key.defaultWeight));
removeNames.UnionWith(names);

Profiler.BeginSample("AutoMergeBlendShape: Merge");
// actually merge data
foreach (var buffer in buffers)
{
Expand Down Expand Up @@ -136,6 +156,8 @@ private static void DoAutoMerge(MeshInfo2 meshInfo2, BuildContext context)
}
}

Profiler.EndSample();

next_shape: ;
}

Expand Down

0 comments on commit dd45e45

Please sign in to comment.