Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

SetPixels and GetPixels of Texture2D behaving unexpectedly

Discussion in 'Scripting' started by KeeganTawa, Oct 25, 2019.

  1. KeeganTawa

    KeeganTawa

    Joined:
    Jan 18, 2019
    Posts:
    9
    Hi everyone! I am trying to manually set the pixels of a texture2D. Here is how I'm doing it (I've altered the code a bit just to create an example that demonstrates my problem):

    Code (CSharp):
    1.             for (int i = 0; i < count; i++)
    2.             {
    3.                 Color color = new Color(randomX, randomY, randomZ, 0f);
    4.                 texture.SetPixel(i, 0, color);
    5.                 texture.Apply();
    6.                 // Print out the first iteration of the loop.
    7.                 if (i == 0) {
    8.                     Debug.Log("Color: " + color);
    9.                     Debug.Log("Texture 0: " + texture.GetPixels()[0]);
    10.                 }
    11.             }
    Strangely, the print results of this code are:

    "Color: 2183, -1059, 1152, 0"
    "Texture 0: 2183, 1, 1, 1"

    It appears that only the first value of the color (its X value) is making it into texture. For the life of me, I can't figure out why.

    Thanks for the help!
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,835
    Not sure why you'd get that specific result, but you should note that the rgba values of a Color are supposed to be in the range of 0-1, and an alpha value of 0 means fully transparent, so the color you were trying to set was not a meaningful value.

    As a side note, you really should only be calling Apply() once, at the very end of the loop, not inside the loop on every iteration. The whole reason it's a separate call is that it's expensive.

    And if you only want to get one pixel, you could use GetPixel(x, y).
     
  3. KeeganTawa

    KeeganTawa

    Joined:
    Jan 18, 2019
    Posts:
    9
    Thanks! Yes, I'm aware Apply() is very costly. I was just running it here as an example to get the log output I wanted to show you guys.

    My texture uses the TextureFormat.RFloat, which takes RGBA values as floats, not 0-1 ranges.
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,835
    SetPixel documentation says: "This function works only on RGBA32, ARGB32, RGB24 and Alpha8 texture formats. For other formats SetPixel is ignored."

    Additionally, I haven't played around with SetPixel personally, but my expectation would be that any argument of type Color is going to interpret its data according to the rules of the Color struct, no matter what it is ultimately being used for. That is, Color.red should still mean "red", and if red has to be represented by different numbers, the function receiving that argument should do the conversion internally.

    Also, I'm not sure what RFloat does, but colors expressed using 0-1 range for each channel are using floats.
     
  5. KeeganTawa

    KeeganTawa

    Joined:
    Jan 18, 2019
    Posts:
    9
    Full disclosure, I am using Texture2D to pass positional information into the Visual Effects Graph - not using it for actual colors. Apparently this is a common practice for moving data into the Visual Effects Graph from script - since you only have a constrained set of data types you can expose.

    In essence I need to move a set of positional coordinates into VFX - My goal is to create a texture, which has an array of colors. Each color has an RGBA float value - these i had hoped to use as coordinate values.
     
  6. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,835
    Well, that's pretty thoroughly outside of my personal expertise, so I suppose I shall just wish you good luck.