Sometimes it can be useful to render to multiple color buffers in a single pass (I.E. a single draw call). For example, if you are writing a deferred renderer, you may want to write to an albedo, normal, depth, specular, and ambient occlusion map all at the same time. In Unity, you can bind multiple color buffers via the Graphics.SetRenderTarget method.
The following image shows the two color buffers being bound as the active render targets to be written to.
I chose to clear both render targets to the color blue.
The image below shows a frame buffer capture where two color buffers have been written to simultaneously as output.
The example below simply writes the colors red and blue to two separate color buffers. One of the colors is rendered via a full-screen quad. You can change which color buffer is displayed by commenting/uncommenting lines 42 and 43.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MultipleColorBufferTest : MonoBehaviour { public Material CustomBlitMaterial; RenderTexture r1; RenderTexture r2; RenderBuffer[] colorRenderBuffers; void Start() { RenderTextureDescriptor d = new RenderTextureDescriptor(Screen.width, Screen.height, RenderTextureFormat.ARGB32); r1 = new RenderTexture(d); r2 = new RenderTexture(d); r1.Create(); r2.Create(); r1.name = "r1 color buffer"; r2.name = "r2 color buffer"; colorRenderBuffers = new RenderBuffer[2] { r1.colorBuffer, r2.colorBuffer }; } void OnRenderImage(RenderTexture src, RenderTexture dst) { Graphics.SetRenderTarget(colorRenderBuffers, r1.depthBuffer); GL.Clear(true, true, Color.blue); CustomBlitMaterial.SetPass(0); GL.PushMatrix(); GL.Viewport(new Rect(0, 0, Screen.width, Screen.height)); // Manually render a full screen quad that will // be either red or green as determined by the custom blit shader. GL.Begin(GL.QUADS); float z = 1f; GL.Vertex(new Vector3(-1, -1, z)); GL.Vertex(new Vector3(-1, 1, z)); GL.Vertex(new Vector3(1, 1, z)); GL.Vertex(new Vector3(1, -1, z)); GL.End(); GL.PopMatrix(); Graphics.Blit(r1, dst); // Render the Red color buffer //Graphics.Blit (r2, dst); // Render the Green color buffer } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
Shader "Unlit/CustomBlit" { Properties { } SubShader { Tags { "RenderType"="Opaque" } Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; } ; struct v2f { float4 vertex : SV_POSITION; } ; v2f vert (appdata v) { v2f o; o.vertex = v.vertex; return o; } struct f2s { fixed4 color0 : COLOR0; fixed4 color1 : COLOR1; } ; f2s frag (v2f i) { f2s o; o.color0 = fixed4(1,0,0,1); o.color1 = fixed4(0,1,0,1); return o; } ENDCG } } } |