How do I call Graphics.DrawTexture correctly?

Graphics.DrawTexture says it draws in screen coordinates. So

public class MyBehaviour : MonoBehaviour
{
    public Texture2D myTexture;

    private void OnPostRender()
    {
        Graphics.DrawTexture(
            new Rect(0, 0, camera.pixelWidth, camera.pixeHeight),
            myTexture));
    }
}

should draw a texture exactly fullscreen. But this is what I get instead:

36648-drawtexture1.jpg

Then I tried

Graphics.DrawTexture(
    new Rect(0, 0, 1, 1),
    myTexture));

and got

36649-drawtexture2.jpg

So it seems that the texture is drawn in some weird, almost-world coordinates. What’s going wrong and how do I fix it? The scene is just the default scene you get in a fresh project. I moved and rotated the camera a bit to illustrate my problem better. Unity version is 4.5.5.

That aren’t almost world space coordinates, that are world space coordinates :wink: (0,0) is (0,0,0) and (1,1) is (1,1,0).

OnPostRender is ment to manually draw arbitrary things. It isn’t specifically ment to render in screen space. You have to setup a matrix manually. Something like this:

GL.PushMatrix();
GL.LoadOrtho();
Graphics.DrawTexture(
    new Rect(0, 0, 1, 1),
    myTexture);
GL.PopMatrix();

Note: 0,0 is the bottom left corner and 1,1 the top right (usual viewport space). Alternativels you can setup a pixel matrix like this:

GL.PushMatrix();
GL.LoadPixelMatrix(0, Screen.width, Screen.height,0);

Graphics.DrawTexture(
    new Rect(0, 0, Screen.width, Screen.height),
    myTexture);
GL.PopMatrix();

LoadPixelMatrix takes 4 parameters: right, left, bottom, top which let you specify any orthographic mapping you want

GL.LoadPixelMatrix(0, 1, 0, 1); // would equal GL.LoadOrtho();
GL.LoadPixelMatrix(0, 1, 1, 0); // same as above but y reversed so 0,0 is top left

edit
Just in case you want to render something in the local space of another object, you have to do this:

public Texture2D myTexture;
public Transform someObject; // use this object's localspace
private void OnPostRender()
{
    GL.PushMatrix();
    GL.LoadProjectionMatrix(camera.projectionMatrix);
    GL.modelview = camera.worldToCameraMatrix * someObject.localToWorldMatrix;
    Graphics.DrawTexture(new Rect(0, 0, 10, 10), myTexture);
    GL.PopMatrix();
}

So we setup the same projection matrix the camera uses to draw the scene and as modelview matrix we set the usual MV matrix (model and view matrix combined in right to left order). Everything you render now will apprear in local space of “someObject”.