Converting a NPOT Texture2D at runtime with SetPixel problem

Hello,

Some time ago I asked a question about converting normal maps at runtime (click) which got anwsered by Aras. It seemed to work correctly but recently we received some textures which are higher than they are wide. When this occurres the texture gets deformed in a weird way.(see below)

The method I’m using for this conversion to a normal map is the same as referenced in the above question:


private Texture2D NormalMap(Texture2D source)
    {
        Texture2D normalTexture = new Texture2D(source.width, source.height, TextureFormat.ARGB32, true);
        //normalTexture.filterMode = FilterMode.Trilinear;
        Color theColour = new Color();

        for (int y = 0; y < source.height; y++)
        {
            for (int x = 0; x < source.width; x++)
            {
                Color newColor = source.GetPixel(x, y);
                theColour.r = 0;
                theColour.g = newColor.g;
                theColour.b = 0;
                theColour.a = newColor.r;
                normalTexture.SetPixel(x, y, theColour);
            }
        }

        normalTexture.Apply();
        return normalTexture;
    }

Case

Now lets say my source image is the following dimensions: width(2027px) height(2048px).
alt text

The image gets loaded from disk and put through the method to be converted and this is the result: (deformed) alt text

Now when we just rotate the image using any Imagine viewer/tool and upload it again this is the result: (correct) alt text

I’ve tried it with multiple textures and if the texture is wider (or equally wide) than it’s high the result is correct. If the texture is higher than it’s wide the deformation is detected. When I read the pixel values after we’ve applied the colors to the texture and I compare them to the original the values are exactly the same even though the texture is deformed. The problem seems to be located in the SetPixel from a NPOT texture that is higher then it’s wide.
Changing the direction in which the pixels are read and set did not work (as expected since I run through all of them)

Does anybody know a solution for this problem? It’s important that the textures keep the same orientation for the application so turning them (even automatic) is not an option.

*Note: I am using Unity 4.6.2f1 for this project


Update 03-04-2015:

Checked it using

Color colors = source.GetPixels();
normalTexture.SetPixels(colors);
normalTexture.Apply();

This gives the same deformation as with the SetPixel one.
Also this does not occur with POT textures even if they are higher than they are wide (I have confirmed this).

It seems to be going wrong in the SetPixel methods in NPOT textures, Unity bug?

I found the solution, it’s not a Unity bug but an oversight on my part.
When I loaded the texture in through the WWW class I first made a placeholder texture of 4x4px in which I loaded the texture using www.LoadImageIntoTexture(). The mistake was trying to keep down memory usage using DXT compression. This obviously does not work with NPOT textures I was using. After loading a texture with the above method everything looks fine. However when you try and read the pixels it will read it from the compressed type and it becomes displaced.

When I changed the placeholder TextureFormat to ARGB32 the problem was solved.