- Home /
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!
Answer by ScroodgeM · Aug 15, 2012 at 06:41 PM
methinks this is what you are searching for. this using in image effects.
If I understand correctly, Blit renders to the destination RenderTexture, and then copies the source Texture on it? How would I use that if I just want to render to my RenderTexture without copying anything on it?
check 'mat' variable
$$anonymous$$aterial to use for copying. $$anonymous$$aterial's shader could do some post-processing effect, for example.
so, i just do the same thing with plane - draw (render) texture with some material
Let's say my material outputs a simple red color with a fragment shader. I just want to have that red color in a RenderTexture (the texture would be a red square). I'm having trouble with the purpose of the "source" texture. Should both src and dest be the same RenderTexture?
Thanks for your help!
you can use Texture with red pixel as source and don't use material
you can also use RenderTexture as source and destination but use material that draws red pixels on whole texture
Thing is, my material does not have any Texture property. It seems Blit() only copies source Texture on destination as "_$$anonymous$$ainTex".
Answer by Banemus · May 22, 2015 at 07:01 AM
I had the same problem and it was solved by adding this line in the shader:
ZTest Always
Your answer
Follow this Question
Related Questions
How to use Graphics.Blit with custom input textures 3 Answers
Blitting to RenderTexture does not seem to be accurate 0 Answers
Render to Texture artifacts 0 Answers
Converting a RenderTexture to a Texture2D for use in a shader 2 Answers
CustomRenderTexture (RFloat) wont initialize in the same frame it is created. 0 Answers