1
\$\begingroup\$

I would like to know how you would go about drawing a single pixel to a RenderTexture in Unity.

In XNA, it was just a matter of setting the graphic device's active renderTarget, and drawing to it.

In Unity, I am unable to figure out how to do this properly. I attempted to use Graphics.DrawTexture, but that seems to be horribly slow.

I imagine there is something that can be done with GL, but I haven't been able to make it draw in side the RenderTexture properly.

Here was my attempt with DrawTexture:

    RenderTexture.active = rt;                      
    GL.PushMatrix();                               
    GL.LoadPixelMatrix(0, 128, 128, 0);            

    for (int x = 0; x < 128; x++)
    {
        for (int y = 0; y < 128; y++)
        {
            Graphics.DrawTexture(new Rect(x, y, 1, 1), texture, mat);
        }
    }

    GL.PopMatrix();  
    RenderTexture.active = null;  
\$\endgroup\$
  • \$\begingroup\$ Is it important that the target be a RenderTexture specifically? If a Texture2D will do, you can use Texture2D.SetPixel or SetPixels (or their Color32 variants). With a RenderTexture, you'd need to render into it with a shader. Judging by your code above, you want to be doing this in script pixel-by-pixel (better suited to the SetPixels methods), rather than the bulk rendering that the shading hardware likes to do with RenderTextures. \$\endgroup\$ – DMGregory Apr 18 '15 at 23:49
9
\$\begingroup\$

enter image description here

Original RenderTexture image on the left, edited Texture2D image on the right.

public class PixelChange : MonoBehaviour {
public RenderTexture renderTexture; // renderTextuer that you will be rendering stuff on
public Renderer renderer; // renderer in which you will apply changed texture
Texture2D texture;

void Start () {

    texture = new Texture2D (renderTexture.width, renderTexture.height);
    renderer.material.mainTexture =  texture;
    //make texture2D because you want to "edit" it. 
    //however this is not a way to apply any post rendering effects because
    //this way, you are reading it through CPU(slow).
}

int at = 0;
// Update is called once per frame
void Update () {
    at++;
    RenderTexture.active = renderTexture; 
    //don't forget that you need to specify rendertexture before you call readpixels
    //otherwise it will read screen pixels.
    texture.ReadPixels (new Rect (0, 0, renderTexture.width, renderTexture.height), 0, 0);
    for (int i = 0; i < renderTexture.width*.2f; i++) 
    for (int j = 0; j < renderTexture.height;j++){
        texture.SetPixel((at +i),j, new Color(1,0,0) );
    }
    texture.Apply (); 
    RenderTexture.active = null; //don't forget to set it back to null once you finished playing with it. 
}
}

Reminder, reading onto texture2D then editing it is slow because Apply call sends chunk of information back go gpu for changed pixels to be applied.

The "correct way" would be writing shader or have "pixel size" object to be drawn onto the final screen, renderTexture.

\$\endgroup\$
  • 1
    \$\begingroup\$ cool post bro . \$\endgroup\$ – zoran404 Apr 19 '15 at 3:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.