Search Unity

Render a Canvas to RenderTexture?

Discussion in 'UGUI & TextMesh Pro' started by comixplay, Oct 7, 2014.

  1. comixplay

    comixplay

    Joined:
    Sep 27, 2013
    Posts:
    104
    Hi guys,
    Is there any way to render a canvas to RenderTexture?

    I want to render the entire screen to RenderTexture, so I'm using:

    RenderTexture rt = new RenderTexture(x, y, 24);
    foreach (Camera cam in Camera.allCameras)
    {
    cam.targetTexture = rt;
    cam.Render();
    cam.targetTexture = null;​
    }

    But it doesn't render the GUI...
     
    Last edited: Oct 9, 2014
  2. comixplay

    comixplay

    Joined:
    Sep 27, 2013
    Posts:
    104
    (bump...)

    Some more info ... The Canvas is set to "Screen Space - Camera"
    The camera is orthographic, and is showing the GUI in the editor and game view.
    cam.redner() renders the skybox or solid color to the renderTexture, but not the GUI.

    Does anyone have any idea? or should I file a bug?
     
  3. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    As much as it saddens me to say this it's likely a bug and you should file one. i'm going to guess that maybe it won't get fixed for v1 but hopefully soon after
     
  4. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    This can probably be worked around by using a screen space - camera UI and setting it to render from your specific camera (set to orthographic mode). The 'overlay' mode doesn't go through the normal render pipeline so it's not injected into a normal camera render.
     
  5. JAKJ

    JAKJ

    Joined:
    Aug 17, 2014
    Posts:
    185
    He says he already is using ScreenSpace-Camera and it's not working.
     
  6. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    Can you actually make the overlay UI "go through a normal render pipeline"?
    Is it possible to capture the UI somehow in a render texture and blit it to the scene behind? A feature like this would be great to enable post processing effects on a canvas.
    Are we stuck using Screen Space - Camera UI in this case?
     
    Finer_Games and demonixis like this.
  7. SunnyChow

    SunnyChow

    Joined:
    Jun 6, 2013
    Posts:
    360
    true. I want to find a way to directly render canvas to RenderTexture
     
  8. LyveIG

    LyveIG

    Joined:
    Jan 8, 2015
    Posts:
    15
    I already did that succesfully. but not with manual rendering though. If the canvas is set to Screen Space - Camera and the Camera has a render texture assigned, this works quite well for me. Not sure what you want to achieve by manual rendering though, thats something I didn't test for the UI yet.
     
    Koyemsi likes this.
  9. SunnyChow

    SunnyChow

    Joined:
    Jun 6, 2013
    Posts:
    360
    In my case, i need to render the canvas into one texture immediately. And then i don't need this canvas anymore. It will be perfect if i can keep this canvas as prefabs in asset folder instead of the scene.

    What i do now is that: I copy this prefabs into scene and create a camera with rendertexture. I call ResetAspect() ResetProjectionMatrix() Render(). And then delete the canvas and the camera. It doesn't work quite well the size of the canvas is wrong. If i let those objects stay, then they can render a correct image in next frame.
     
  10. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Has someone solved this?
     
  11. lucashaley

    lucashaley

    Joined:
    May 26, 2006
    Posts:
    8
  12. J_P_

    J_P_

    Joined:
    Jan 9, 2010
    Posts:
    1,027
    renderTexture.jpg

    I combine multiple cameras onto a single rendertexture before blitting to the screen, but my world space canvases are missing :(
     
    ristophonics likes this.
  13. JonnyHilly

    JonnyHilly

    Joined:
    Sep 4, 2009
    Posts:
    749
    Same problem.... Unity5, trying to get some nice screenshots from a button press during gameplay.. I have a single camera with canvas, screen space overlay gui, but the gui does not show up on the Camera.Render()
    (also tried world-space and screen-space-camera) all with the same result... no gui rendered.
    Any update to this problem ? bug ?
     
  14. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    i think there is a backport request waiting to be processed to get his fixed.
     
  15. J_P_

    J_P_

    Joined:
    Jan 9, 2010
    Posts:
    1,027
    Tested my world canvases in 3.5.0b6 and it seems to be fixed
     
  16. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    Going to assume you mean 5.3.0b6 :) but glad to hear hopefully the backport will land in 5.2 "soon"
     
    Cromfeli and J_P_ like this.
  17. Aiursrage2k

    Aiursrage2k

    Joined:
    Nov 1, 2009
    Posts:
    4,835
    Does this work because it seems like it still doesnt work
     
  18. Nintenjo64

    Nintenjo64

    Joined:
    May 19, 2015
    Posts:
    12
    Cannot get the UI to render to a texture for me on 5.3.1f1 only seems to work with a World Space camera.. not a screen spaced one :(
     
  19. horkyze

    horkyze

    Joined:
    Sep 21, 2012
    Posts:
    4
    Experiencing same problem with 4.6.9p3
     
  20. alvifarooq

    alvifarooq

    Joined:
    Sep 14, 2015
    Posts:
    21
    Hi,

    Any update on this issue? I'm using 5.3.2f1 and it's not working.
    Any suggested workarounds?

    Regards,

    Farooq
     
    Noxury likes this.
  21. subjectZero

    subjectZero

    Joined:
    Oct 19, 2014
    Posts:
    37
    Echo, Echo, echoooooooo....

    Same here peeps. mine is running on unity 5.3.4f1 and my canvas is set at screen space - overlay

    Anyone know about a workaround?
    Was the bug made?
     
    Last edited: May 23, 2016
    Noxury likes this.
  22. joegatling

    joegatling

    Joined:
    Jul 16, 2013
    Posts:
    7
    I am seeing this issue in 5.3.4p6
     
  23. Cromfeli

    Cromfeli

    Joined:
    Oct 30, 2014
    Posts:
    202
  24. Noxury

    Noxury

    Joined:
    Mar 8, 2015
    Posts:
    22
    Last edited: Jun 4, 2016
  25. subjectZero

    subjectZero

    Joined:
    Oct 19, 2014
    Posts:
    37
    sorry guys i figured it out and forgot to post it.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. //using System.IO;
    4.  
    5. public class MyScreenShotUI : MonoBehaviour {
    6.  
    7.  
    8.     void Start(){
    9.  
    10.  
    11.  
    12.     }
    13.  
    14.  
    15.     public void myScreenShot(){
    16.  
    17.         StartCoroutine (TakeScreenShot());
    18.  
    19.     }
    20.  
    21.  
    22.     IEnumerator TakeScreenShot() {
    23.  
    24.         yield return new WaitForEndOfFrame();
    25.  
    26.  
    27.         var width = Screen.width;
    28.         var height = Screen.height;
    29.         var tex = new Texture2D( width, height, TextureFormat.RGB24, false );
    30.  
    31.  
    32.         tex.ReadPixels( new Rect(0, 0, width, height), 0, 0 );
    33.         tex.Apply();
    34.  
    35.  
    36.     }
    37.  
    38. }
    just call myScreenShot(); in your code somewhere. So "tex" now has the screen shot value, make any public texture equal to that value to use it. Hope it works for you.
     
    Last edited: Jun 6, 2016
    vrgz, Laulaurene and Rodolfo-Rubens like this.
  26. Dan-MacDonald

    Dan-MacDonald

    Joined:
    Oct 25, 2013
    Posts:
    17
    Nice I'll give this a shot!
     
  27. subjectZero

    subjectZero

    Joined:
    Oct 19, 2014
    Posts:
    37
    cool,

    please let me know, it works for me.
     
  28. Agent_007

    Agent_007

    Joined:
    Dec 18, 2011
    Posts:
    899
    Works fine in editor when width == Screen.width and height == Screen.height but it cannot be used to create bigger than current resolution screenshots.
     
  29. subjectZero

    subjectZero

    Joined:
    Oct 19, 2014
    Posts:
    37
    sorry i don't follow, why would you want to create a screen shot of something bigger than the actual resolution? a screenshot by definition can't be bigger than itself. Your taking a image of what the current screen sees (that is what this thread is about, right?) and even if so,the result will be pixelated, don't you think?

    but yea i get where your coming from, every device will have a different size, but maybe thats just how it goes... or am i missing something? now I'm confused, can one tell it at what size to take the screen capture?
     
  30. Agent_007

    Agent_007

    Joined:
    Dec 18, 2011
    Posts:
    899
    Use cases for bigger renderings are getting those glamour shots (like Mega Grab https://www.assetstore.unity3d.com/en/#!/content/533 does) and UI testing. AFAIK currently it is not possible to get e.g. 3840 x 2160 shot from game with UGUI if one has 1920 x 1080 resolution monitor. That is why it would be REALLY useful if Canvas could be rendered to RenderTexture.
     
    firstuser likes this.
  31. ikriz

    ikriz

    Joined:
    Dec 3, 2009
    Posts:
    98
    ScreenCapture.CaptureScreenshot("file.jpg",4);

    will give you a large capture 4x the size of your resolution.
     
    Songshine likes this.
  32. Koyemsi

    Koyemsi

    Joined:
    Sep 25, 2017
    Posts:
    29
    I confirm. On the Canvas component, I set Plane Distance to 0.3 (which corresponds to the camera near plane), and I also had to modify values on the Canvas Scaler (Scale Factor to 0.5)
     
  33. SunnyChow

    SunnyChow

    Joined:
    Jun 6, 2013
    Posts:
    360
    sadly, there is still no good method to render canvas to rendertexture.

    (no ScreenCapture.CaptureScreenshot() is not, World-Space either unless you like filters messing up your 2d ui)
     
  34. JonR79

    JonR79

    Joined:
    May 13, 2018
    Posts:
    9
    Oh wow. I just wanted to render my screen to a texture with the UI overlay on it still. I didn't realize I would have to read 7 years worth of comments and conversation just to learn that Unity has not addressed this problem...

    Oh well.
     
  35. unity_vD8AxOEcL15PKQ

    unity_vD8AxOEcL15PKQ

    Joined:
    Dec 29, 2021
    Posts:
    2
    Still nothing?
     
  36. LightRuno

    LightRuno

    Joined:
    May 2, 2018
    Posts:
    7
    Holy moly, still nothing in here...
     
  37. Leonin

    Leonin

    Joined:
    Nov 13, 2014
    Posts:
    4
    1) Set "Render Camera" in Canvas to your camera.
    2) Create script with this code:

    Code (CSharp):
    1.  
    2. [RequireComponent(typeof(Camera))]
    3. public class Blitter : MonoBehaviour
    4. {
    5.     private RenderTexture temporaryRT;
    6.     private Camera mainCamera;
    7.  
    8.     private RenderTexture target;
    9.  
    10.     private void Awake()
    11.     {
    12.         mainCamera = GetComponent<Camera>();
    13.     }
    14.  
    15.     private void OnPreRender()
    16.     {
    17.         temporaryRT = RenderTexture.GetTemporary(Screen.width, Screen.height);
    18.         mainCamera.targetTexture = temporaryRT;
    19.     }
    20.  
    21.     private void OnPostRender()
    22.     {
    23.         Graphics.Blit(temporaryRT, target);
    24.         mainCamera.targetTexture = null;
    25.  
    26.         RenderTexture.ReleaseTemporary(temporaryRT);
    27.     }
    28. }
    29.  
    30.  
    4) Attach it to camera setted for render canvas
    5) Use RenderTexture target anywhere you need.
     
    Last edited: Oct 29, 2023