I'm trying to copy the scene rendered by a particular camera to a render target. I know this should be possible to do without using the camera's target texture as I read through this official Unity article about Command Buffers which avoids any use of them.
Instead, I found that they use the following code in the renderer for blurry refractions (CommandBufferBlurRefraction.cs) to copy the scene to a render target.
buf = new CommandBuffer();
buf.name = "Grab screen and blur";
m_Cameras[cam] = buf;
// copy screen into temporary RT
int screenCopyID = Shader.PropertyToID("_ScreenCopyTexture");
buf.GetTemporaryRT(screenCopyID, -1, -1, 0, FilterMode.Bilinear);
buf.Blit(BuiltinRenderTextureType.CurrentActive, screenCopyID);
The problem is that I can't get this to work for myself using a very simple scenario of:
- Camera renders the entire scene which is a single hexagonal sprite
- The command buffer assigned to the camera grabs the BuiltinRenderTextureType.CurrentActive (Scene Render Target)
- The command buffer then copies that to another render target
- That render target is then drawn in the upper left of the screen on a yellow background
This results in the scene render target being completely blank and not including the white hexagon.
The code I am using is
Camera cameraUsedToRender;
CommandBuffer commandBuffer;
RenderTexture debugRT;
Texture2D debugRTBackground;
void Awake()
{
// Create debug texture to render
debugRTBackground = new Texture2D(2, 2);
debugRTBackground.SetPixels(new Color[4] { Color.yellow, Color.yellow, Color.yellow, Color.yellow });
debugRTBackground.Apply();
cameraUsedToRender = Camera.main;
cameraUsedToRender.orthographicSize = 10f;
// Create debug render texture to render to using our camera
debugRT = new RenderTexture(cameraUsedToRender.pixelWidth, cameraUsedToRender.pixelHeight, 16);
debugRT.Create();
// Create command buffer
commandBuffer = new CommandBuffer();
commandBuffer.name = "Debug";
// Add the camera buffer to the main camera
cameraUsedToRender.AddCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, commandBuffer);
}
void OnRenderObject()
{
// Clear the command buffer
commandBuffer.Clear();
// Set the render target
commandBuffer.SetRenderTarget(debugRT);
// Clear the render target
commandBuffer.ClearRenderTarget(true, true, Color.blue);
// Copy scene into a render target
// RenderTarget.active = SceneView RT (UnityEngine.RenderTexture)
commandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, debugRT);
// Release the render target
commandBuffer.SetRenderTarget(null as RenderTexture);
}
void OnGUI()
{
// Draw the debug render target (which should have the SceneView RT copied to it)
GUI.DrawTexture(new Rect(0, 0, 130, 130), debugRTBackground);
GUI.DrawTexture(new Rect(1, 1, 128, 128), debugRT);
}
The complete small, simple project that demonstrates this issue can be found here.
Does anyone have an idea how to resolve this as I'm finding the Unity rendering pipeline to be rather confusing at this point?