Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Set all pixels to be red (255,0,0) using Texture2D.SetPixelData, but the pixels change to a multicolour assortment

I have the following code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TextureScript : MonoBehaviour
{

    Texture2D texture;

    // Start is called before the first frame update
    void Start()
    {
        texture = new Texture2D(256,256, TextureFormat.RGB24, true);

        var rectTransform = transform.GetComponent<RectTransform>();
        rectTransform.sizeDelta = new Vector2(texture.width, texture.height);

        int pixelCount = texture.width * texture.height;

        Queue<Color> queue = new Queue<Color>();

        for(int i = 0; i < pixelCount; i++)
        {
            queue.Enqueue(new Color(255,0,0));
        }

        Color[] colorArray = queue.ToArray();

        texture.SetPixelData(colorArray, 0, 0);
        texture.filterMode = FilterMode.Point;
        texture.Apply(updateMipmaps: false);

        GetComponent<RawImage>().material.mainTexture = texture;
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

Which produces this:

The image produced by aforementioned code.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I am unsure as to what could be producing it. Previously I was using a byte array for tests which worked, but my work now requires a queue, and to then convert this queue into an array (which I have done using .ToArray()).

I also used RGBA32 rather than RGB24 with varying alpha values of 255, 128, 1, & 0; however, this produced a nearly see-through image each time.

Thank-you for your help.

>Solution :

  • Why use a Queue instead of simply an array?
  • Why use SetPixelData instead of simply SetPixels?

I would simply do e.g.

//var pixels = texture.GetPixels();
// or even simply
var pixels = new Color[texture.width * texture.height];
for(var i = 0; i < pixels.Length; i++)
{
    pixels[i] = color.Red;
}
texture.SetPixels(pixels);
texture.Apply();

SetPixelData is rather

useful if you want to load compressed or other non-color texture format data into a texture.

What happens in your case is: Color has a byte size of 4 float (=16 byte) since it also has an alpha value! Your texture is using RGB24 and therefore only expecting 3 bytes (=24 bit) per pixel.

So in case you really want to stick to that (might be faster – or not ^^) you would rather have to do e.g.

var pixels = new byte[texture.width * texture.height * 3];
for(var i = 0; i < pixels.Length; i+=3)
{
    pixels[i] = 255; // R
    pixels[i+1] = 0; // G
    pixels[i+2] = 0; // B
}
texture.SetPixelData(pixels, 0, 0);
texture.Apply();

also regarding

new Color(255,0,0)

note that Color takes float arguments from 0 to 1. If you are looking for a byte based input rather go for Color32 and SetPixels32


Further note that RawImage is actually quite expensive – you could stick to an Image component and simply create a Sprite from your Texture2D

GetComponent<Image>().sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 0.5f);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading