Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Non power of two sprites on Android

Discussion in '2D' started by vallis_unity, May 6, 2023.

  1. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    Hi, not sure if I'm running into a bug here or just not understanding something about the way things work in Android builds. The project in question is using Unity 2023.1.0b15, 2D pixel art style using the pixel perfect camera, URP, Android.

    When using a sprite of a completely arbitrary size (say 150x150 pixels) everything just seems to work in the editor. After building onto an android device and running it on a phone (Samsung S21 Ultra) there is some "pixel swimming" observed on the sprite. This changes depending on where the sprite is on the screen, and in some positions can completely disappear, only to reappear again after moving.

    Packing the texture into an atlas reduces the amount of pixel swimming, but does not eliminate it entirely. Strangely, it often only seems to occur on the right hand side of the sprite when using an atlas. I've tried using the V1 and V2 sprite atlas system, but results are the same on both.

    I can completely resolve the situation by saving the sprite as a 256x256 sprite (with some padding) and then using borders in the sprite editor to get back to what I need. Unfortunately, although this clears up the pixel swimming, it means that colliders set to the size of the sprite are misaligned (and makes authoring sprites more annoying).

    Is the behaviour on Android expected here? Is it just less flexible than running on PC/editor in regards to non power of two sprite/textures? Shouldn't packing arbitrary sized sprites into an atlas completely bypass those restrictions anyway?

    Many thanks!
     
  2. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    Adding some screenshots in the hope this makes things clearer. I made a test pattern PNG file which is 125x87 and put it on a black background in a test scene.

    Here is the raw asset file:

    pattern.png

    Here is what it looks like running in the editor (correct):

    editor.png

    Here is what it looks like on a Samsung S21 Ultra with sprite atlas disabled (pixel swimming):

    no-atlas.png

    Here is what it looks like on a Samsung S21 Ultra with sprite atlas enabled (pixel swimming):

    with-atlas-1.png

    with-atlas-2.png

    I include two shots on the last category to show how it looks at two different positions on the screen. The reason I describe the issue as "pixel swimming" is because when the sprite (or the camera) is in motion the sprite rapidly moves between different incorrectly filtered states such as these.

    I haven't been able to test this on other devices yet, but am hoping to get some confirmation on whether this is expected on Android devices, or if this looks likely to be a bug?
     
  3. DavidTeo

    DavidTeo

    Unity Technologies

    Joined:
    Apr 1, 2021
    Posts:
    69
    Hello, sorry about the delay in reply.

    I've tried to reproduce your issue on my end locally with your created asset on a Samsung Galaxy S8+ to no avail, with / without the use of sprite atlas. Will you be able to provide your bug project, or even better create a bug report and let us know the report number?
     
    vallis_unity likes this.
  4. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    Hi @DavidTeo, thanks for the reply and the bug report is IN-40632. There is some back and forth with a reviewer (Timi) on there where we managed to hone in on the issue, but there hasn't been any response since last month.

    It seems that the problem only occurs when the device is set to non-native resolution and the texture/atlas uses point filtering. My phone's native resolution is WQHD+ (3200x1440) and when set to that there is no issue, but when the phone is set to FHD+ (2400x1080) it reproduces as above.

    Very happy to help investigate/test anything.
     
  5. DavidTeo

    DavidTeo

    Unity Technologies

    Joined:
    Apr 1, 2021
    Posts:
    69
    Hello @vallis_unity, thanks and I saw your bug report. Unfortunately there's a lapse on responses of late as the main developer is currently on vacation.

    I've tried to reproduce the issue by decreasing the screen resolution of the device from (QHD+ 2220x1080 to HD+ 1480x720), removing the movement script and even doubled the scale of the sprite asset in the scene, but I didn't see the issue on the Android device on my end unfortunately.
     

    Attached Files:

  6. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    Hi @DavidTeo, that's interesting. I rebuilt my test APK using 2023.1.0b20 and changed my resolution to HD+ and that also doesn't show any issues for me. I still have the same pixel swimming issue at FHD+ (2400x1080) though, and it's still fine at native WQHD+ (3200x1440).

    What is even more surprising is that at HD+ I still see swimming issues in my main game project. The sprites there are different sizes etc though and the swimming is harder to see when not using a test pattern. It's definitely there though.

    Is there any way you are able to try on a device with a WQHD+ screen (set to FHD+) to replicate what I'm seeing in the test app?
     
  7. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    Screenshot of the build I just made running at FHD+ on an S21 Ultra.

    Screenshot_20230621_114459_AndroidSprite.png
     
  8. DavidTeo

    DavidTeo

    Unity Technologies

    Joined:
    Apr 1, 2021
    Posts:
    69
    Hello @vallis_unity , unfortunately I left Galaxy S8+ on-site and only have access to an old Pixel 2 phone.

    The Galaxy S8+ is already capable of QHD 1440p, but the default which is set to is FHD 1080p and also tried to decrease it to HD 720p in my previous test. So I think that device fulfils that criteria.

    I've still ran it on Pixel2 with 2023.1.0b20 which you provided earlier but didn't exhibit the issue in its 1920x1080 resolution.
    I've proceeded to revert the scale back to 1, and saw that there seem to be some display issues on the Non-power of two sprite render on the top. is that what you are referring to? upload_2023-6-22_15-7-7.png
     
  9. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    @DavidTeo That actually looks worse than I've ever seen it. I have not seen the jagged effect exhibited in your screenshot. If you compare against the most recent screenshot I posted you can see it is a much milder effect, and only impacts filtering along the horizontal axis.

    Perhaps these are still the same underlying issue and some complex combination of native resolution, display resolution, texture resolution, GPU, and drivers can cause different types of texture filtering issues?
     
  10. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    Hi @DavidTeo, do you have any updates on this following your repro above? Does this look like there's a bug, or am I doing something incorrectly or misunderstanding something? Many thanks!
     
  11. Venkify

    Venkify

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    639
    It is usually recommended to use POT sprite textures (either directly in source sprite size of simply using Atlas which ensures POT) especially for Pixel Perfect use-cases. Under the hood, sampling pixels from POT textures mostly results in uniform results across platforms/api/drivers. However usage of NPOT textures may result in such artifacts depending on varios factors such as format, size, filters etc..
    For best results where each pixel matters, please use SpriteAtlas and uncompressed formats such as RGBA32.
     
    vallis_unity likes this.
  12. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    Thanks for the reply @Venkify. A couple of follow up questions to ensure I am understanding things here:
    1. Am I wrong in thinking that creating arbitrary NPOT sprites for the game (freeing asset creation from any kind of technical concern) should be fine as long as I am using a (POT sized) atlas? Or does every single sprite need to be POT sized and in a POT atlas?
    2. If individual sprites need to be POT, can their dimensions vary or must they be uniform? For example. is a 256x32 sprite acceptable or would it need to be padded out to 256x256?
     
  13. Venkify

    Venkify

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    639
    Sprites just need to be added to SpriteAtlas and SpriteAtlas textures are always POT. (note: There may be cases where this may still result in artifacts for certain compressed formats using block based compression. )

    There dimensions can vary as long as both are POT.
     
    vallis_unity likes this.
  14. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    @Venkify I am still seeing this issue with uncompressed textures and when using a sprite atlas (mode: Sprite Atlas V2 - Enabled). I've taken some screenshots to walk through everything in case you can see anything wrong:

    First, here is the POT texture (128x128):

    texture-pot.png

    Secondly, here is the NPOT texture (125x87):
    texture-npot.png

    The texture atlas is configured as follows:
    atlas.png

    Running on device, with the NPOT texture on top, this exhibits the following filtering issue on device:
    screenshot.png

    I have tried changing the texture settings to force "RGBA 32 bit" and this does not result in any differences. Follow up questions:
    1. With the atlas enabled and given what you have said above, surely there should be no filtering issue in this scenario?
    2. What is the extraneous texture information in the atlas to the right of the NPOT texture? The pixel data present there is not present in any of the source textures, so I'm curious where it's coming from. Even if it lies outside the texture's area this seems a little strange.
    3. Why is there no padding between the textures in the atlas, when the padding option is set to 4? Making changes to this setting does not seem to alter the atlas preview at all.
    Edit: It looks like questions 2 and 3 can be resolved by enabling Alpha Dilation on the texture atlas. Question 1 remains the primary issue, I just wondered if what I observed in 2 & 3 might be clues.
     
    Last edited: Jun 28, 2023
  15. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    @Venkify @DavidTeo Sorry to tag again, but any final say on the above? Whether I am safely able to use NPOT sprites from an atlas or not is somewhat fundamental to my art pipeline. Being prevented from using NPOT sprites means padding them and having the sprite colliders be a different size than the sprite, which I would much rather avoid if possible.

    If the above is confirmed as a bug I can carry on as I am and hope a fix lands in time for when I'm ready to launch.
     
  16. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    @Venkify @DavidTeo I have recorded a video of the issue directly on a device to try and increase visibility. This demonstrates the issue that while using a texture atlas NPOT textures are incorrectly sampled.

    I have attached the video directly as YouTube compression completely killed it. The forum required me to zip it up in order to post it, but it's just an MP4 file inside.

    It would be really useful if this could be clarified as either working as intended or a bug, as it impacts how I need to manage the art pipeline for the game I'm working on.

    I reported this as a bug back in early May but the ticket has been stalled for a couple of months now: https://unity3d.atlassian.net/servicedesk/customer/portal/2/IN-40632

    Many thanks!
     

    Attached Files:

  17. Venkify

    Venkify

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    639
    This artifact seems to depend on the driver (rasterizer) while sampling the pixel from the texture. We managed to reproduce the issue in a few devices but not on others. Would suggest using POT sprites for such use-cases.
     
  18. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    @Venkify Thanks for the update, and I'm glad you were able to pin things down to certain drivers.

    Does your recommendation imply that this isn't something that is considered a bug for the Unity team? That there will not be any further investigation into the cause or any attempt to resolve it? Or do you suggest it as a temporary fix while the issue is ongoing? You say "for such use-cases" but what is my use case here - I'm not doing anything esoteric.

    If it's the former, it feels like not being able to use NPOT sprites in a pixel art mobile game is a little concerning. While sprites could all be padded with transparency, this has knock on effects for many other engine systems (colliders and physics, for example) which will be frustrating to be always working around.

    If I 100% know this issue will not be resolved and has to be worked around then there is an overhaul of all existing assets for my game to be carried out, along with a new workflow for asset authoring. Sorry to belabour the point with you but I'm really keen to get as much clarification on this before I make the decision on which approach to take.

    To give an example of why this seems so concerning to me: if my test devices had all happened to be ones which did not exhibit the texture sampling issues, I would never have been aware of this issue. After years of development and everything looking perfect in the editor and on my test devices I would go to release my game only to discover that the sprites are garbled on many device types. The only solution would be to reauthor all of the games sprites (with padding) and then deal with all the collider/physics/etc knocks on resulting from that change - all to work around an issue I never knew existed. Perhaps the change might even increase the size of the texture atlases (due to all the padding) so that the game has to raise its device memory requirements, etc etc.
     
  19. Venkify

    Venkify

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    639
    @vallis_unity Can you please provide a few more sample sprites that exhibits this behavior? This will help diagnose the issue further. Thanks.
     
  20. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    Unfortunately I don't have any to share as I stopped creating new assets after I first ran into this issue. I've been working on other aspects of the game until I know whether NPOT sprites are an option or not. Basically the first issue I ran into that exhibited this behaviour was 125x87 and these are the dimensions I used to create the test pattern texture I've been using in the repro project.

    That said I have just done some testing by resizing the test texture and running on my phone. I'm honestly a little baffled at the results. I kept things to just altering the height for these tests, as that seemed unpredictable enough on its own. Here are the tests I ran with their results, in the order I ran them.

    Code (csharp):
    1. 125x87  = issues (the sampling issues appear on the right of the texture in this test)
    2. 125x86  = issues
    3. 125x40  = issues (subjectively, this looks worse than the above two tests)
    4. 125x100 = no problems
    5. 125x200 = no problems
    6. 125x99  = issues
    7. 125x101 = no problems
    8. 125x20  = issues (the sampling issues appear on the left of the texture in this test)
    9. 125x50  = no problems
    10. 125x49  = no problems
    11. 125x48  = issues (really bad, across the entire width of the texture)
    12. 125x47  = no problems
    13. 125x46  = no problems
    14. 125x45  = no problems
    15. 125x44  = no problems
    16. 125x43  = issues
    17. 125x42  = issues
    18. 125x41  = issues
    19. 125x40  = issues
    20. 125x39  = issues
    21. 125x38  = issues
    22. 125x37  = issues
    If there is a pattern here I am not seeing it. At least the results are consistent and deterministic, I re-tested the same dimensions a few times and it always produced the same outcome.

    If you'd like more data points please let me know and I'll be happy to do more tests and share the results.
     
    Last edited: Jul 26, 2023
  21. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73
    Hi @Venkify, wondering if there is any update on this? Was the above data of any use?

    I'd love some clear feedback on whether or not this is being seen as a bug by the Unity team.
     
  22. vallis_unity

    vallis_unity

    Joined:
    Apr 14, 2022
    Posts:
    73