Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by AleksLA · Sep 16, 2015 at 12:33 PM · spritesatlaspacktexturespacking

Unity 5.2 Sprite packer too slow

I just switched from Unity 4.6 to Unity 5.2, and after all the trouble of updating various libraries and classes to resolve the compatibility issues, I realized that packing of the sprites into atlases has changed the way it works. Before I was able to repack all Sprites for less then a minute, and now it takes a good 6 hours to do it. Does anyone knows a way to improve the performance of that or if there is a fix coming soon?

Thank you in advance.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by AleksLA · Sep 17, 2015 at 12:10 PM

After a lot of investigations it turns out, the performance loss is due to the fact of the quality of compression of the textures. TextureCompressionQuality.Best is doing good compression, but takes long time, so it is better to avoid it for faster building. My solution is simply to to make a new Packer Policy that uses low compression quality for debugging, and only when doing release builds to change it to the regular Default Packer Policy.

This is the sample that I modified that works great and now the packing is very fast ( I just modified the version from here http://docs.unity3d.com/Manual/SpritePacker.html and put the quality to hardcoded number 40 )

 using UnityEngine;
 using System.Collections;
 
 using System;
 using System.Linq;
 using UnityEngine;
 using UnityEditor;
 using System.Collections.Generic;
 
 
 public class DefaultPackerPolicySampleToNormal : UnityEditor.Sprites.IPackerPolicy
 {
     protected class Entry
     {
         public Sprite sprite;
         public UnityEditor.Sprites.AtlasSettings settings;
         public string atlasName;
         public SpritePackingMode packingMode;
         public int anisoLevel;
     }
     
     private const uint kDefaultPaddingPower = 3; // Good for base and two mip levels.
     
     public virtual int GetVersion() { return 1; }
     protected virtual string TagPrefix { get { return "[TIGHT]"; } }
     protected virtual bool AllowTightWhenTagged { get { return true; } }
     protected virtual bool AllowRotationFlipping { get { return false; } }
     
     public static bool IsCompressedFormat(TextureFormat fmt)
     {
         if (fmt >= TextureFormat.DXT1 && fmt <= TextureFormat.DXT5)
             return true;
         if (fmt >= TextureFormat.DXT1Crunched && fmt <= TextureFormat.DXT5Crunched)
             return true;
         if (fmt >= TextureFormat.PVRTC_RGB2 && fmt <= TextureFormat.PVRTC_RGBA4)
             return true;
         if (fmt == TextureFormat.ETC_RGB4)
             return true;
         if (fmt >= TextureFormat.ATC_RGB4 && fmt <= TextureFormat.ATC_RGBA8)
             return true;
         if (fmt >= TextureFormat.EAC_R && fmt <= TextureFormat.EAC_RG_SIGNED)
             return true;
         if (fmt >= TextureFormat.ETC2_RGB && fmt <= TextureFormat.ETC2_RGBA8)
             return true;
         if (fmt >= TextureFormat.ASTC_RGB_4x4 && fmt <= TextureFormat.ASTC_RGBA_12x12)
             return true;
         if (fmt >= TextureFormat.DXT1Crunched && fmt <= TextureFormat.DXT5Crunched)
             return true;
         return false;
     }
     
     public void OnGroupAtlases(BuildTarget target, UnityEditor.Sprites.PackerJob job, int[] textureImporterInstanceIDs)
     {
         List<Entry> entries = new List<Entry>();
         
         foreach (int instanceID in textureImporterInstanceIDs)
         {
             TextureImporter ti = EditorUtility.InstanceIDToObject(instanceID) as TextureImporter;
             
             TextureFormat desiredFormat;
             ColorSpace colorSpace;
             int compressionQuality;
             ti.ReadTextureImportInstructions(target, out desiredFormat, out colorSpace, out compressionQuality);
             
             TextureImporterSettings tis = new TextureImporterSettings();
             ti.ReadTextureSettings(tis);
             
             Sprite[] sprites =
                 AssetDatabase.LoadAllAssetRepresentationsAtPath(ti.assetPath)
                     .Select(x => x as Sprite)
                     .Where(x => x != null)
                     .ToArray();
             foreach (Sprite sprite in sprites)
             {
                 Entry entry = new Entry();
                 entry.sprite = sprite;
                 entry.settings.format = desiredFormat;
                 entry.settings.colorSpace = colorSpace;
                 // Use Compression Quality for Grouping later only for Compressed Formats. Otherwise leave it Empty.
                 entry.settings.compressionQuality = IsCompressedFormat(desiredFormat) ? 40 : 0;
                 entry.settings.filterMode = Enum.IsDefined(typeof(FilterMode), ti.filterMode)
                     ? ti.filterMode
                         : FilterMode.Bilinear;
                 entry.settings.maxWidth = 2048;
                 entry.settings.maxHeight = 2048;
                 entry.settings.generateMipMaps = ti.mipmapEnabled;
                 entry.settings.enableRotation = AllowRotationFlipping;
                 if (ti.mipmapEnabled)
                     entry.settings.paddingPower = kDefaultPaddingPower;
                 else
                     entry.settings.paddingPower = (uint)EditorSettings.spritePackerPaddingPower;
                 entry.atlasName = ParseAtlasName(ti.spritePackingTag);
                 entry.packingMode = GetPackingMode(ti.spritePackingTag, tis.spriteMeshType);
                 entry.anisoLevel = ti.anisoLevel;
                 
                 entries.Add(entry);
             }
             
             Resources.UnloadAsset(ti);
         }
         
         // First split sprites into groups based on atlas name
         var atlasGroups =
             from e in entries
                 group e by e.atlasName;
         foreach (var atlasGroup in atlasGroups)
         {
             int page = 0;
             // Then split those groups into smaller groups based on texture settings
             var settingsGroups =
                 from t in atlasGroup
                     group t by t.settings;
             foreach (var settingsGroup in settingsGroups)
             {
                 string atlasName = atlasGroup.Key;
                 if (settingsGroups.Count() > 1)
                     atlasName += string.Format(" (Group {0})", page);
                 
                 UnityEditor.Sprites.AtlasSettings settings = settingsGroup.Key;
                 settings.anisoLevel = 1;
                 // Use the highest aniso level from all entries in this atlas
                 if (settings.generateMipMaps)
                     foreach (Entry entry in settingsGroup)
                         if (entry.anisoLevel > settings.anisoLevel)
                             settings.anisoLevel = entry.anisoLevel;
                 
                 job.AddAtlas(atlasName, settings);
                 foreach (Entry entry in settingsGroup)
                 {
                     job.AssignToAtlas(atlasName, entry.sprite, entry.packingMode, SpritePackingRotation.None);
                 }
                 
                 ++page;
             }
         }
     }
     
     protected bool IsTagPrefixed(string packingTag)
     {
         packingTag = packingTag.Trim();
         if (packingTag.Length < TagPrefix.Length)
             return false;
         return (packingTag.Substring(0, TagPrefix.Length) == TagPrefix);
     }
     
     private string ParseAtlasName(string packingTag)
     {
         string name = packingTag.Trim();
         if (IsTagPrefixed(name))
             name = name.Substring(TagPrefix.Length).Trim();
         return (name.Length == 0) ? "(unnamed)" : name;
     }
     
     private SpritePackingMode GetPackingMode(string packingTag, SpriteMeshType meshType)
     {
         if (meshType == SpriteMeshType.Tight)
             if (IsTagPrefixed(packingTag) == AllowTightWhenTagged)
                 return SpritePackingMode.Tight;
         return SpritePackingMode.Rectangle;
     }
 }
 
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

2 People are following this question.

avatar image avatar image

Related Questions

Does Unity 2D tools generate atlas? 1 Answer

How to rebuild Atlas manually? 1 Answer

Get a sprite's atlas during build 0 Answers

Adding sprites to "Objects for Packing" list in a SpriteAtlas through code? 1 Answer

Get the atlas of a sprite in editor 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges