diff --git a/CHANGELOG-PRERELEASE.md b/CHANGELOG-PRERELEASE.md index 70bb51b7..746f2362 100644 --- a/CHANGELOG-PRERELEASE.md +++ b/CHANGELOG-PRERELEASE.md @@ -18,6 +18,7 @@ The format is based on [Keep a Changelog]. ### Removed ### Fixed +- basic Mesh Renderers are not considered in Optimize Texture `#1328` ### Security diff --git a/CHANGELOG.md b/CHANGELOG.md index 0187a045..5faf85c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ The format is based on [Keep a Changelog]. - We may relax some restriction in the future. - Because we have to check for each condition if we use AnyState but we can check for only one (in best case) with entry/exit, this generally reduces cost for checking an parameter in a state. - Combined with Entry / Exit to 1D BlendTree optimization, which is implemented in previous release, your AnyState layer may be optimized to 1D BlendTree. -- Optimize Texture in Trace nad Optimize `#1181` `#1184` `#1193` `#1215` `#1225` `#1235` `#1268` `#1278` `#1313` +- Optimize Texture in Trace nad Optimize `#1181` `#1184` `#1193` `#1215` `#1225` `#1235` `#1268` `#1278` `#1313` `#1328` - Avatar Optimizer will pack texture and tries to reduce the VRAM usage. - Currently liltoon is only supported. - `Copy Enablement Animation` to Merge Skinned Mesh `#1173` diff --git a/Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs b/Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs index c9928735..8c4e28a5 100644 --- a/Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs +++ b/Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs @@ -309,7 +309,12 @@ public static void DoMerge(BuildContext context, target.ClearMeshData(); target.SubMeshes.Capacity = Math.Max(target.SubMeshes.Capacity, materials.Count); foreach (var material in materials) + { target.SubMeshes.Add(new SubMesh(material.material, material.topology)); + if (material.material != null + && context.GetMaterialInformation(material.material) is { } information) + information.UserRenderers.Add(target.SourceRenderer); + } TexCoordStatus TexCoordStatusMax(TexCoordStatus x, TexCoordStatus y) => (TexCoordStatus)Math.Max((int)x, (int)y); diff --git a/Editor/Processors/TraceAndOptimize/OptimizeTexture.cs b/Editor/Processors/TraceAndOptimize/OptimizeTexture.cs index 56a7c15b..260370c0 100644 --- a/Editor/Processors/TraceAndOptimize/OptimizeTexture.cs +++ b/Editor/Processors/TraceAndOptimize/OptimizeTexture.cs @@ -135,6 +135,7 @@ internal class MaterialNode : UnionFindNodeBase { // If we cannot collect textures from shader information (if null), unable to merge public List? TextureUsageInformations { get; set; } + public List? UserRenderersOnAvatar { get; set; } // The list of submeshes that use this material public List Users { get; } = new(); @@ -229,6 +230,7 @@ BuildContext context if (materialInformation?.TextureUsageInformationList is { } informations) { materialNode.TextureUsageInformations = informations.ToList(); + materialNode.UserRenderersOnAvatar = materialInformation.UserRenderers.Where(x => x != null).ToList(); textures = informations.Select(x => ((Texture2D?)material.GetTexture(x.MaterialPropertyName), (TextureUsageInformation?)x)); @@ -293,6 +295,12 @@ BuildContext context if (info.Materials.Any(mat => mat.TextureUsageInformations == null)) return Array.Empty<(EqualsHashSet, AtlasResult)>(); + // the material should not be used by other renderers. + // we're ignoring basic Mesh Renderers so we have to check if the material is not used by basic Mesh Renderers. + var renderers = info.SubMeshes.Select(x => x.SubMeshId.MeshInfo2.SourceRenderer).ToHashSet(); + if (info.Materials.Any(mat => mat.UserRenderersOnAvatar == null || !renderers.SetEquals(mat.UserRenderersOnAvatar))) + return Array.Empty<(EqualsHashSet, AtlasResult)>(); + var textureByUvId = new Dictionary>(); var uvidByTexture = new Dictionary>();