Search Unity

Texture2D.SetPixel behaving unexpectedly

Discussion in 'Scripting' started by MariusRu, Nov 13, 2019.

  1. MariusRu

    MariusRu

    Joined:
    Oct 15, 2015
    Posts:
    33
    Dear forum,

    I am trying to create Texture2D objects from scratch via code. For instance, I used the following code to get a simple red texture.

    Code (CSharp):
    1.     public Texture2D CreateTexture2D()
    2.     {
    3.         Texture2D texture = new Texture2D(128, 128);
    4.         for (int i = 0; i < 128; i++)
    5.         {
    6.             for (int j = 0; j < 128; j++)
    7.             {
    8.                 Color col = Color.red;
    9.                 texture.SetPixel(i, j, col);
    10.             }
    11.         }
    12.         texture.Apply(false);
    13.         return texture;
    14.     }
    However, what I get instead is an image with vertical stripes in four colors (see attached). What's going on here? (btw my approach to save images as .png works for other Texture2D objects, so that should not be the problem).

    Thank you,
    Marius
     

    Attached Files:

  2. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    1,553
    The code looks correct to my eye, and I also ran it here and it produced a red texture when I did that once in Start. You are most likely doing something else that inferes with your image saving, I'd bet.
     
    MariusRu likes this.
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    For clarity: if you use this texture in-game, do you see the same stripe pattern? Just because saving a texture works fine with textures generated in other ways doesn't mean it's being used correctly for a texture created in this way. There's a lot of different formats and stuff for textures that could affect the way saving PNGs work.

    Aside from that, two things:
    First, I suspect this is some kind of color format issue. You may want to try one of the other constructors that include color space information?

    Second, calling SetPixel repeatedly is agonizingly slow compared to SetPixels. SetPixels is, in turn, agonizingly slow compared to using a RenderTexture. Changing to SetPixels may or may not affect the current problem, but using a RenderTexture almost certainly would bypass anything that would cause this issue, in addition to being lightning fast in comparison and much more versatile. Of course everything depends on your use case and why you need to do this, but it's extraordinarily rare for anything but RenderTexture to be the best solution.
     
    MariusRu likes this.
  4. MariusRu

    MariusRu

    Joined:
    Oct 15, 2015
    Posts:
    33
    Thank you both for your comments and hints to speed up the process.

    Indeed, it was a problem with saving the image as PNG (you were right: just because my approach to saving the data worked for other Texture2D objects did not mean it would always work).

    In my experience, the simple "System.IO.File.WriteAllBytes(_fullPath, _bytes);" is most robust when saving images.