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

[solved] Texture2D.GetPixel() suddenly broken?

Discussion in 'Scripting' started by Dokkanosaur, Jul 20, 2017.

  1. Dokkanosaur

    Dokkanosaur

    Joined:
    Jul 18, 2017
    Posts:
    11
    Hi all,

    I've been using a function in one of my custom editors for about a year now that I wrote to get the individual textures of a multi-sprite. For months and months this has worked flawlessly for me, but today seemingly for no reason, I'm getting completely busted and blurry results. Here's the code:

    public static Texture2D GetTextureFromSprite(Sprite s, FilterMode f){
    var rect = s.rect;

    var tex = new Texture2D((int)rect.width, (int)rect.height);
    Color[] data = s.texture.GetPixels((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);

    tex.SetPixels(data);
    tex.Apply(true);
    tex.fillterMode = f;
    return tex;
    }

    I've narrowed the issue down to the GetPixels(), which appears to do something to the effect of sampling the entire image down to 50% and then scaling it up, giving a "blurry" effect.

    I thought at first that the image filtermode was being set to bilinear, but this is not the case, the filtermode is in fact behaving correctly. I'm not scaling the image at all, as you can see, just grabbing the exact "rect" as stored in the sprite data and spitting it out into a new texture. I even tried using nested for loops and pulling each pixel individually... no dice, same result.

    Right: The actual sprite in Unity's SpriteEditor
    Left: Output of the above function.

    (they should both look the same)




    To reiterate, I have been using this exact script for about a year, no problems at all. I'm getting these results on sprites I imported months ago that were all rendering just fine up until this morning. To my knowledge, not a single thing has changed that could mess this up...

    What the heck is going on? Can anyone replicate this? Am I losing my mind?
     
  2. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,083
    It sounds more like it's grabbing the wrong mipmap level although it should always get the '0' level by default. You could try making sure that 'generate mip maps' is off on your sprite though. If you want to make up a test project showing it happening I can have a look.
     
  3. Dokkanosaur

    Dokkanosaur

    Joined:
    Jul 18, 2017
    Posts:
    11
    Hey tonemcbride,

    "generate mipmaps" is definitely turned off, and I'd even tried setting the mipmap level to 0 while troubleshooting, just in case unity was somehow generating them despite me.

    I may have to come back after doing some deeper digging on my own when I've got time. I've yet to check if the problem persists on other installs of unity / on other systems. If all else fails, I'll send something through for you to have a look at.

    Thanks for your suggestion!

    Edit: Just to add to this:

    If you look at the code above, if i just return s.texture, essentially skipping the function and returning the input, the result is perfectly sharp. So from what I can tell... whatever is happening to make things blurry / undersampled is happening inside of this function, with this new texture.
     
    Last edited: Jul 24, 2017
  4. Dokkanosaur

    Dokkanosaur

    Joined:
    Jul 18, 2017
    Posts:
    11
    Okay, I solved it.

    Mipmaps were the culprit, it seems, but not with the source sprite. They actually were being auto-set for the generated texture, seen in the line below:

    var tex = new Texture2D((int)rect.width, (int)rect.height);

    The solution?

    var tex = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGBA32, false);

    The last parameter explicitly turns mipmaps off. Still very confused why this behaviour changes on its own.
    I'll reiterate again, this did not behave this way for months and months, but now for me at least apparently it does. I hope that I accidentally set some default behaviour preference somewhere, because then it would be my fault and explainable. No idea how it happened, otherwise.

    If such a setting exists, could someone point me to it?
     
  5. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,083
    That's odd, I was going to suggest setting it to false in the 'new Texture2D' part but it should default to that (as you said) so that's why I didn't mention it.
     
  6. Dokkanosaur

    Dokkanosaur

    Joined:
    Jul 18, 2017
    Posts:
    11
    Yeah, totally.

    You may not have explicitly mentioned it but I wouldn't have thought of it if you hadn't suggested to turn mipmaps off, so thanks!