Author Topic: Sprite Atlas Broken on IOS (Fixed)  (Read 13465 times)

psngui

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 9
    • View Profile
Re: Sprite Atlas Broken on IOS (Fixed)
« Reply #15 on: September 29, 2014, 10:36:37 PM »
The problem with largest size is that our game runs out of memory on iOS. We have to downsize all the textures manually (without using the override settings), and manually refresh the atlas to make it work. We considered it as a temporary workaround and was looking for an official solution. Are you saying that there is nothing NGUI can do about it?

EDIT: There seems to be miscellaneous information in .meta file of atlases (.png), e.g., maxTextureSize. Maybe worth a look?
« Last Edit: September 29, 2014, 11:06:31 PM by psngui »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Sprite Atlas Broken on IOS (Fixed)
« Reply #16 on: September 30, 2014, 04:22:16 AM »
Max texture size is just the maximum allowed texture size on import.

If you are running out of memory, reduce your texture usage. Many people have massive atlases full of epic size full screen textures. This is obviously quite ridiculous. Keep large textures outside atlases. Atlases are for small textures. Likewise, keep long / narrow sprites outside atlases as well. If you have a sprite that's 1000x32 for example, then you're doing it wrong. Very wrong. Take advantage of 9-slicing and layering components on top of each other in order to get the look you want instead.

psngui

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 9
    • View Profile
Re: Sprite Atlas Broken on IOS (Fixed)
« Reply #17 on: October 01, 2014, 02:20:34 AM »
Hi ArenMook,

I just did a file comparison on an atlas between before and after applying override settings of iOS and here are my findings:

1. One (and only file) is changed: the atlas (.png.meta) file.
2. textureFormat is changed from 5 to -3
3. textureSettings/aniso is changed from 4 to 1
4. nPOTScale is changed from 1 to 0
5. buildTargetSettings is changed from [] to the followings:
- buildTarget: iPhone
  maxTextureSize: 4096
  textureFormat: -3
  compressionQuality: 50

All I did was ticking the Override for iPhone then clicking Apply, in which case Max Size is 4096. If Max Size is changed to say 1024, then it will be 'maxTextureSize: 1024' in the .png.meta file.

I believe this information is sufficient for NGUI to update atlases accordingly.

I know that UnityEditor.Callbacks.PostProcessScene can be used to get notified just before a scene is built. According to the doc, BuildTarget and/or RuntimePlatform can be used to determine target platform (I'm not sure about this one). It seems that an automated process can be added to NGUI to generate iOS (or whatever platform with overridden settings) atlases using the override settings.

If that's not possible, at least a manual process (a button for example) can be added to fulfill the need.

Please let me know if any of these is possible.


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Sprite Atlas Broken on IOS (Fixed)
« Reply #18 on: October 01, 2014, 05:19:49 PM »
1. I don't care what the max texture size is. I need to know the original texture size, not the max texture size.

2. You are assuming users have text-based metadata files, which is wrong by default. Default is binary.

psngui

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 9
    • View Profile
Re: Sprite Atlas Broken on IOS (Fixed)
« Reply #19 on: October 01, 2014, 08:06:19 PM »
There is a default maxTextureSize value, and there is an override maxTextureSize value.

With the two values, we can update atlases in these steps:
1. Calculate the ratio of the override value against the default value. Typical values can be: 1/2, 1/4, 1/8, etc.
2. Iterate through all the atlases and do the following steps
   a) Iterate through all the sprites in the atlas
   b) For every sprite, find the relevant source image file, resize it (create new may be a good idea) with the ratio calculated
   c) After all the image files are generated, recreate the atlas with the new image files

To solve that binary/text-based problem, you just have to add a line in NGUI readme file or web page, something like this: If you are going to use Override settings on atlases, you have to enable xxxxxx, which is located at xxxxx. I'm sure you can come up with much better way of saying it.

There is a reason why Unity provide override settings for atlases: some projects, including ours, want to manage images in a way that they are suitable for high-end devices, with the capability to downscale to fit low-end devices, in a convenient way; or in other words, there is only one copy of all the images and they are in highest resolutions.

The mess-up of UI when using atlas' override settings is a bug (or an incomplete feature) of NGUI. I'd think as the author of NGUI, you'd care to perfect your product. (I think NGUI is great, by the way.) However, if you are too busy or reluctant to do it because maybe only a few people use this feature, it will be appreciated if you can validate my theory so that I can do it myself.

Thanks.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Sprite Atlas Broken on IOS (Fixed)
« Reply #20 on: October 02, 2014, 10:05:55 PM »
Once again... I don't care what the "max texture size" setting is. Nor what the override "max texture size" setting is.

Imagine this scenario. You have a 1740x1100 texture. Yes, odd dimensions like that. You import it into Unity. Your desktop's quality is set to a high setting, but still by default that texture gets imported as 2048x1024 because Unity will want it to be power of two unless you change it. The "max texture size" is 2048 by default.

So now you get this texture into your game and realize that it's not proper size. Alright, change the import settings: allow NPOT. Now the texture is correctly 1740x1100.

Now you want this same thing on a mobile device. But hey, you set the texture to be compressed, and on a mobile device that means PVRTC. PVRTC can't do rectangular textures. They must be square. So now your texture gets imported as 2048x2048.

Queue in another android device that can't do 2048, or simply targeting GLES 1.1. Your texture is now 1024x1024. You can choose to override the texure import settings for android to turn off the compression to make it possible to have a rectangle, but then not all devices may get supported. You may also choose to override it to simply change it to something else. Regardless, this doesn't help you figure out what the texture's original size (1740x1100) was from code.

Are you following me now?

xod

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 1
    • View Profile
Re: Sprite Atlas Broken on IOS (Fixed)
« Reply #21 on: October 06, 2014, 11:51:27 PM »
Your scenario is flawed.

I dont care about full screen textures. I dont care about rectangular textures. I dont care about odd pixels dimensions. I care about all the sprite coordinates getting messed up when using alternate mip levels of a 4096x4096 texture because all your code uses pixel coordinates.

Packing textures at max res is a great idea, because devices that can handle those size textures look immaculate. Saving sprite coordinates in pixels instead of UVs is flawed because it means you cant upload different texture mip levels (whether they be generated online or offline) for lesser devices without having to recalculate everything.

In mobile development this is a massive, massive flaw. I have written texture packers before for a couple of different companies, and its not a difficult task at all, so I'm not sure why you are so resistant to it.

If you are point blank not going to do it for whatever reason, could you at least point me in the right direction to modify the NGUI source code so that it does what we want?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Sprite Atlas Broken on IOS (Fixed)
« Reply #22 on: October 07, 2014, 10:25:48 AM »
Pixels are easier to work with. Pixels make sense. People understand pixels. Professionals also understand texture coordinates, sure -- but when the inspector shows values like 0.194663 and 0.846426, what does that tell the average user other than bring confusion?

When the user wants to specify a 4 pixel border around the sprite... should he do it in pixels, or in texture coordinates? If in texcoords, how do you translate 4 pixels into texture coordinate equivalent? Bust out a calculator? If in pixels -- why pixels now? Where to draw the line between using pixels and texture coordinates? How will the two intermix? What if you want to scale the atlas texture, and now all the values you specified in pixels get fubared? You may say "just do conversion on the fly and store texcoords under the hood!". Well, guess what Unity themselves use when you pack textures? Also pixels.

Furthermore, typical GUI textures are rarely dividable by two, or have dimensions that make sense. 17x21 sprites? Certainly. If you think you can simply take a texture and reduce its size to half, consider what will happen to your 17x21 sprites that will suddenly get dimensions of 8.5x10.5 in pixels. Does that make sense in any form anymore?

As I mentioned earlier in the thread, if you want to take your atlas and downscale it, and you are absolutely certain that you won't run into any issues I mentioned above, then go ahead and do just that. Write an editor script that will take the atlas, loop through its array of sprites then automatically convert their coordinates using whatever math you desire. You can then apply the same logic to the texture itself (such as reducing it down to half size), and everything will work without having to touch any NGUI's code.