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!