Render material to full screen quad

Hi,

I’m trying to render a material to a full-screen quad, and then saving the image to a Texture2D.

This is my current implementation, which works :

public Material material;
public int width = 1024, height = 1024;
public Texture2D noiseTex;
private RenderTexture heightmap;

void Start()
{
    heightmap = new RenderTexture(width, height, 24);
    noiseTex = new Texture2D(width, height, TextureFormat.ARGB32, false);
}

void Update()
{
    GetHeightMap();
}

void GetHeightMap()
{
    // Create an orthographic camera that points to the created plane below
    GameObject renderCamera = new GameObject();
    renderCamera.AddComponent<Camera>();
    renderCamera.GetComponent<Camera>().backgroundColor = Color.black;
    renderCamera.GetComponent<Camera>().orthographic = true;
    renderCamera.GetComponent<Camera>().orthographicSize = 5;
    renderCamera.GetComponent<Camera>().transform.localPosition = new Vector3(9999, 10009, 9999);
    renderCamera.GetComponent<Camera>().transform.localRotation = Quaternion.Euler(new Vector3(90.0f, 0.0f, 0.0f));

    // Create a plane that occupies all the created camera's view and assign the material
    GameObject renderPlane = GameObject.CreatePrimitive(PrimitiveType.Plane);
    renderPlane.transform.localPosition = new Vector3(9999, 9999, 9999);
    renderPlane.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, 0));
    renderPlane.GetComponent<MeshRenderer>().material = material;

    RenderTexture.active = heightmap;

    // Render a frame and save it to a Texture2D
    renderCamera.GetComponent<Camera>().targetTexture = heightmap;
    renderCamera.GetComponent<Camera>().Render();
    noiseTex.ReadPixels(new Rect(0.0f, 0.0f, heightmap.width, heightmap.height), 0, 0);
    renderCamera.GetComponent<Camera>().targetTexture = null;
    noiseTex.Apply();

    // Clean up
    RenderTexture.active = null;
    DestroyImmediate(renderPlane);
    DestroyImmediate(renderCamera);
}

Now, I know this is not the best way to achieve this goal. I tried with the following method, which I think is the standard way to render a full-screen material, but the output Texture2D is always blank (completely black) :

void GetHeightMap2()
{
    GameObject renderCamera = new GameObject();
    renderCamera.AddComponent<Camera>();
    renderCamera.camera.backgroundColor = Color.white;
    renderCamera.camera.orthographic = true;
    renderCamera.camera.orthographicSize = 5;

    RenderTexture.active = heightmap;

    renderCamera.camera.targetTexture = heightmap;

    GL.PushMatrix();
    for (int i = 0; i < material.passCount; i++)
    {
        material.SetPass(i);
        GL.LoadOrtho();
        GL.Viewport(new Rect(0, 0, 1024, 1024));

        GL.Begin(GL.QUADS);
        GL.TexCoord2(0, 0);
        GL.Vertex3(0.0F, 0.0F, 0);
        GL.TexCoord2(0, 1);
        GL.Vertex3(0.0F, 1.0F, 0);
        GL.TexCoord2(1, 1);
        GL.Vertex3(1.0F, 1.0F, 0);
        GL.TexCoord2(1, 0);
        GL.Vertex3(1.0F, 0.0F, 0);
        GL.End();
    }
    GL.PopMatrix();

    // Read pixels
    noiseTex.ReadPixels(new Rect(0.0f, 0.0f, heightmap.width, heightmap.height), 0, 0);
    noiseTex.Apply();

    // Clean up
    renderCamera.camera.targetTexture = null;
    RenderTexture.active = null;
    DestroyImmediate(renderCamera);
}

Shouldn’t the two methods be equivalent? What am I missing?

Thanks for your help!

methinks this is what you are searching for. this using in image effects.

I had the same problem and it was solved by adding this line in the shader:

ZTest Always