How can I get Unity to stop resampling my sprites?

I am rendering sprites as a single texture on a quad. Unfortunately, Unity resamples the texture to the nearest power of two which affects the artwork when it is a different size (eg. 24x24). I can zoom in during play and see that the texture has become a 32x32 one. The texture is set to Point mode so bilinear filtering is off.

I have tried setting the asset to the ‘GUI’ texture mode, but it is still being resampled. Similarly if I go to ‘Advanced’ texture mode and leave the nearestPowerOfTwo mode on ‘None’, it is resampled then, as well.

Anybody have any suggestions?

Example image, Scene view on left, original asset on right:

And a close-up of how the texture appears in the preview after importing, to show it was imported correctly:
7053-texture_sampling_issue_2.png

UPDATE: For reference: the whole internal-rescaling-to-POT-for-NPOT-textures issue is fixed in Unity 4 (tested 4.2.0)! The following discussion/answer is about older versions, such as Unity 3.5:

Assuming it really is a bug, I can at least suggest a workaround. It is ugly, tedious, and hackish, but it will resolve your problem:

  • pad your textures manually to be 32x32
  • either adapt your object UV to the new mapping scale (and maybe origin), or adapt the scale/offset settings in the material using the texture.

For example, extend your texture to the right and the bottom, to keep the “correct” texture segment in the upper left corner. Then you can set the texture scaling to 0.75/0.75 instead of 1/1 in the material.

If you keep your sprite centered while padding on all four sides, you’d have to adjust the offset, too.

EDIT:

I checked this again with an old testscene I did about this problem, and unfortunately it is still present (latest version tested: 3.5.7. The issue is actually fixed in 4.x (tested 4.2.0). Problem exists at least since 2.6.

====> Any non-power-of-two-textures will be resampled to the nearest(?) power-of-two, even if NPOT-scaling is explicitly set to “None”. An exception are GUI textures, i.e. if you use such a texture for OnGUI() or in GUITexture objects. But any such texture applied to a “regular” GameObject will no longer be pixel-perfect compared to the original texture. See also Aras’ answer here (although he does not explicitly mention that the scaling also happens if you set NPOT-scaling to “None”).

I guess it is debatable whether this is a bug or a feature - I consider it a bug, since if I explicitly set the texture scaling to “leave-the-texture-alone-and-dont-use-NPOT-scaling”, I expect the system to do exactly that. If it is unable to do that due to hardware limitations (or whatever other reasons) it at the very least needs to explain this drawback in the documentation.

EDIT2: Woops, as @Bunny83 pointed out, it is documented, somewhere in the fine print :wink:

Read the section about Texture Sizes. As you can see when NPOT textures are used as “normal” textures they are converted internally to POT textures. I’m not sure why they do that, but it seems you can’t disable this behaviour. It might be for compatibility with graphics cards which don’t support NPOT textures.

However the easiest and best fix is to resize your texture to 32x32 (add padding). NPOT textures are even slower. The graphics card memory is optimised for POT sizes. Even NPOT textures will use the next higher POT size alignment in graphics memory.

Do you set the color format to TrueColor? Its default value is ‘Compressed’ and will be blurred.

i am not sure that is really possible in unity, i think my approach would be to make them textures a much higher resolution.

actually i have some 2d art left over from my construct classic obsession, i have all this scaled up 4x from 16x16 to sharpen the aliasing. I imagine in unity I’d scale up even more still and maybe customize the actual edges depending how the alpha goes down.

basically you’re gonna just have to use a tonne of more memory and get down and dirty with it but in a systematic way preferably, I’d suggest investigating programmable batch type image manipulation tool like imagemagic so you can mass process stuff

That is happening because you are using a texture with dimensions that are not a power of 2. You can stop Unity from resizing the texture by either using the GUI texture type or Advanced with “Non Power of 2” set to “None,” but I’m not sure how much of an impact this will have on performance

From the Texture documentation:

It is possible to use other (non power of two) texture sizes with Unity. Non power of two texture sizes work best when used on GUI Textures, however if used on anything else they will be converted to an uncompressed RGBA 32 bit format. That means they will take up more video memory (compared to PVRT(iOS)/DXT(Desktop) compressed textures), will be slower to load and slower to render (if you are on iOS mode). In general you’ll use non power of two sizes only for GUI purposes.

You could also combine multiple sprites onto a single larger texture and change the UVs of the quad to get just the sprite you want. This is called a texture atlas

Couldn’t you just add the sprite to a sprite sheet (which is PoT) and then change the texture co-ords of the quad? That should give you pixel perfect sprites and work more optimally.