Texture2D/Rect/rendertexture Coordinate System / Extracted part of texture results in wrong part

Hello there,

I have a function to copy or extract a part of a readonly texture.
My assumption is, that the coordinate system is bottom/left and the extracted part is also the rectangle spanned from the bottom left corner.

    public static Texture2D ExtractTexture(Texture2D source, Rect window)
    {
        RenderTexture renderTex = RenderTexture.GetTemporary(
                    source.width,
                    source.height,
                    0,
                    RenderTextureFormat.ARGB32,
                    RenderTextureReadWrite.Default);

        RenderTexture previous = RenderTexture.active;

        Graphics.Blit(source, renderTex);
        RenderTexture.active = renderTex;

        Texture2D readableText = new Texture2D((int)window.width, (int)window.height, TextureFormat.ARGB32, false, true);
        readableText.ReadPixels(window, 0, 0);
        readableText.Apply();

        RenderTexture.active = previous;
        RenderTexture.ReleaseTemporary(renderTex);

        return readableText;
    }

This test works:

[Test]
public void Test_ExtractTexture_16px()
{
    Texture2D input = new Texture2D(4, 4, TextureFormat.ARGB32, false, true);

    for (int x = 0; x < input.width; ++x)
    {
        for (int y = 0; y < input.height; ++y)
        {
            if (x > 1 || y > 1)
            {
                input.SetPixel(x, y, x % 2 == 0 ? Color.red : Color.blue);
            }
            else
            {
                input.SetPixel(x, y, x % 2 == 0 ? Color.green : Color.white);
            }

        }
    }

    //   r b r b
    //   r b r b
    //   g w r b
    //   g w r b
    // x 0 1 2 3

    // Apply all SetPixel calls
    input.Apply();

    Assert.AreEqual(4, input.width);
    Assert.AreEqual(4, input.height);
    Assert.AreEqual(Color.green, input.GetPixel(0, 0));
    Assert.AreEqual(Color.green, input.GetPixel(0, 1));
    Assert.AreEqual(Color.white, input.GetPixel(1, 0));
    Assert.AreEqual(Color.white, input.GetPixel(1, 1));

    Assert.AreEqual(Color.red, input.GetPixel(2, 2));
    Assert.AreEqual(Color.red, input.GetPixel(2, 3));
    Assert.AreEqual(Color.blue, input.GetPixel(3, 2));
    Assert.AreEqual(Color.blue, input.GetPixel(3, 3));

    Assert.AreEqual(Color.red, input.GetPixel(0, 2));
    Assert.AreEqual(Color.red, input.GetPixel(0, 3));
    Assert.AreEqual(Color.blue, input.GetPixel(1, 2));
    Assert.AreEqual(Color.blue, input.GetPixel(1, 3));

    Assert.AreEqual(16, input.GetPixels().Length);

    Texture2D output = SpriteUtils.ExtractTexture(input, new Rect(1, 1, 2, 2));

    Assert.AreEqual(2, output.width);
    Assert.AreEqual(2, output.height);
    Assert.AreEqual(4, output.GetPixels().Length);

    Assert.AreEqual(Color.white, output.GetPixel(0, 0));
    Assert.AreEqual(Color.blue, output.GetPixel(0, 1));
    Assert.AreEqual(Color.red, output.GetPixel(1, 0));
    Assert.AreEqual(Color.red, output.GetPixel(1, 1));
}

But somehow this test fails:

[Test]
public void Test_ExtractTexture_mapsize()
{
    Texture2D input = new Texture2D(480, 576, TextureFormat.ARGB32, false, true);

    for (int x = 0; x < input.width; ++x)
    {
        for (int y = 0; y < input.height; ++y)
        {
            input.SetPixel(x, y, Color.clear);
        }
    }

    for (int x = 0; x < input.width; x += 96)
    {
        for (int y = 0; y < input.height; y += 96)
        {
            Color setColor = Color.blue;
            if ((x + y / 96) % 2 == 0)
            {
                setColor = Color.red;
            }
            Debug.Log(x + " , " + y + " , " + setColor);
            input.SetPixel(x, y, setColor);
        }
    }
    input.Apply();
    Rect r = new Rect(0, 288, 96, 96);
    Debug.Log(r);
    Debug.Log(r.yMin + " " + r.yMax);
    Debug.Log(r.xMin + " " + r.xMax);
    Texture2D output = SpriteUtils.ExtractTexture(input, new Rect(0, 288, 96, 96));

    Assert.AreEqual(Color.blue, output.GetPixel(0, 0));
    Assert.AreEqual(Color.clear, output.GetPixel(0, 1));

    Texture2D output2 = SpriteUtils.ExtractTexture(input, new Rect(96, 288, 96, 96));
    Assert.AreEqual(Color.red, output2.GetPixel(0, 0));
    Assert.AreEqual(Color.clear, output2.GetPixel(0, 1));

}

The pixel a x 0, y 288 should be blue but somehow the extracted pixel is a red one and i don’t find my error.

I believe, its something stupid i don’t see, maybe you can help me :slight_smile:
Thanks!

I found, that if the texture height is higher than the width, the y axis is somehow flipped. Strange behaviour.