Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

How to include post processing in manual camera render?

Discussion in 'General Graphics' started by hasseyg, May 15, 2020.

  1. hasseyg

    hasseyg

    Joined:
    Nov 16, 2013
    Posts:
    78
    Hi, I am using Unity 2019.3.13 and URP. I want to take a super resolution screenshot from a particular camera in the game and have always used the same code for this. Now I have run into the problem that the bloom effect is not being included in the image. The code I had been using in LateUpdate is:

    Code (CSharp):
    1.  
    2. RenderTexture rt = new RenderTexture(resWidth , resHeight, 24);
    3.             rt.antiAliasing = 8;
    4.             camera.targetTexture = rt;
    5.             Texture2D screenShot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false);
    6.            
    7.             camera.Render();
    8.             RenderTexture.active = rt;
    9.             screenShot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0);
    10.             camera.targetTexture = null;
    11.             RenderTexture.active = null;
    12.             Destroy(rt);
    13.             byte[] bytes = screenShot.EncodeToPNG();
    14.             string filename = string.Format("C:\\Desktop\\screen" + (counter++).ToString() + ".png");
    15.             System.IO.File.WriteAllBytes(filename, bytes);
    16.        
    Does anyone know what a fix might be?

    thanks
     
  2. AxonGenesis

    AxonGenesis

    Joined:
    Jun 24, 2016
    Posts:
    82
    I am running into this very same issue today, though in edit mode. In play mode, you can solve this by using a coroutine and waiting for the frame to finish rendering.

    Code (CSharp):
    1.  
    2. void LateUpdate()
    3.     StartCoroutine(_RenderFrame());
    4. }
    5.  
    6. protected IEnumerator _RenderFrame()
    7. {
    8.     yield return new WaitForEndOfFrame();
    9.  
    10.     // Then your code to capture the image
    11. }
    I'm still trying to figure out a way to do this in edit mode.
     
  3. AxonGenesis

    AxonGenesis

    Joined:
    Jun 24, 2016
    Posts:
    82
    I believe I found a viable solution for my purposes. Maybe it will help you or others trying to do the same. Here is the basic code outline. One caveat to this approach is you cannot use camera.Render(), or at least it resulted in a pipeline error about recursive rendering. So instead, I'm using CaptureScreenshotAsTexture to get the existing camera texture without re-rendering.

    Code (CSharp):
    1.  
    2. using UnityEngine.Rendering;
    3. public void EditorStartSequence()
    4. {
    5.     RenderPipelineManager.endCameraRendering += EndCameraRendering;
    6. }
    7.  
    8. public void EditorStopSequence()
    9. {
    10.     RenderPipelineManager.endCameraRendering -= EndCameraRendering;
    11. }
    12.  
    13. private void EndCameraRendering(ScriptableRenderContext context, Camera camera)
    14. {
    15.     if (camera == myCamera) { // check which camera in case you have multiple rendering cameras
    16.         screenShot = ScreenCapture.CaptureScreenshotAsTexture(ScreenCapture.StereoScreenCaptureMode.LeftEye);
    17.         // then save to file using screenShot.EncodeToPNG();
    18.     }
    19. }
    20.  
     
  4. hasseyg

    hasseyg

    Joined:
    Nov 16, 2013
    Posts:
    78
    Ok, thanks for your reply, I will use your first suggestion, as I have a vr project where I want to capture a screenshot from a 3rd camera and using ScreenCapture only captures from the headset.