Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by jptsetung · Jan 25, 2013 at 03:16 AM · texture2drendertexturescreenshot

RenderTexture to Texture2D

In the following piece of code that is supposed to take a screenshot, I don't understand why we need to call screenShot.ReadPixels to get Texture2D. A RenderTexture is already a texture, do we really need to use a time consuming operation like ReadPixel to turn it into a Texture2D? Can't we directly render a camera into a Texture2D? (In Cocos2d, there is a class called CCRenderTexture that extends CCTexture and that can be used to render scenes into. So there must be a way to do so, at least with OpenGL.)

     public static void ScreenShot() {
         RenderTexture rt = new RenderTexture((int)Futile.screen.pixelWidth, (int)Futile.screen.pixelHeight, 24);
         Futile.instance.camera.targetTexture = rt;
         Texture2D screenShot = new Texture2D((int)Futile.screen.pixelWidth, (int)Futile.screen.pixelHeight, TextureFormat.RGB24, false);
         Futile.instance.camera.Render();
         RenderTexture.active = rt;
         screenShot.ReadPixels(new Rect(0, 0, (int)Futile.screen.pixelWidth, (int)Futile.screen.pixelHeight), 0, 0);
         Futile.instance.camera.targetTexture = null;
         RenderTexture.active = null;
         //DestroyImmediate(rt);
         var bytes = screenShot.EncodeToPNG();
         System.IO.File.WriteAllBytes(Application.dataPath + "/screenshots/screen" + System.DateTime.Now.ToString("dd-MM-yyyy_HH-mm-ss") + ".png", bytes);
     }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

4 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Eric5h5 · Jan 25, 2013 at 03:23 AM

You can't render a camera into a Texture2D; you can only render it into a RenderTexture. A RenderTexture is a Texture, but it's not a Texture2D. Both RenderTexture and Texture2D inherit from Texture. The RenderTexture is not accessible from main memory, so yes you do need to convert it.

Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jptsetung · Jan 25, 2013 at 12:48 PM 1
Share

How disappointing it is. $$anonymous$$y tests with RenderTextures give horrible performances, it's not usable on every frame. $$anonymous$$aybe I'm doing something wrong, I hope so.

avatar image Dave-Carlile · Jan 25, 2013 at 04:51 PM 0
Share

A render texture can be assigned directly to a material (http://docs.unity3d.com/Documentation/Components/class-RenderTexture.html), so the bits stay in GPU memory. When you transfer data from GPU to CPU there will always be a performance hit.

avatar image Eric5h5 · Jan 25, 2013 at 06:51 PM 0
Share

RenderTexture has very fast performance. You don't need to convert to a Texture2D normally.

avatar image jptsetung · Jan 25, 2013 at 09:58 PM 1
Share

Thx Eric and Dave, that was my error. Now that I'm using RenderTexture directly in the $$anonymous$$aterial, it runs smooth.

avatar image Pangamini · Jun 21, 2019 at 07:41 AM 1
Share

ReadPixels shouldn't be costly, it's performed entirely on GPU, AFAI$$anonymous$$ (not copying data to the CPU/memory). Recalculating mip-maps adds some cost, so disable it if you don't need it.

avatar image atrajano Pangamini · Jun 21, 2019 at 07:44 AM 1
Share

I can concur with that. Its the "GetPixels" that is costly.

avatar image Pangamini atrajano · Jun 21, 2019 at 08:22 AM 0
Share

I just noticed that ReadPixels also does Gfx.ReadBackImage which seems slow. I am going to try Graphics.CopyTexture and tell you how it performs

Show more comments
avatar image
-1

Answer by Wolfram · Jan 25, 2013 at 12:52 PM

Simply use Application.CaptureScreenshot.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jptsetung · Jan 25, 2013 at 12:59 PM 0
Share

I didn't really want to make a screenshot, just understanding why rendering into a RenderTexture is so slow in Unity whereas it was so smooth with Cocos2d (direct OpenGL calls).

avatar image
0

Answer by atrajano · Jun 21, 2019 at 06:49 AM

I find the EncodeToPNG very slow. What you can do is get the color32 and use System.Graphics to render it for you.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Pangamini · Jun 21, 2019 at 08:51 AM

I've just done a little research (coz i needed a similar thing) ReadPixels() does a GPU->CPU readback, which is very slow. Now depending on what you need, you can either

  • Use the RenderTexture directly in your further rendering. This is NOT suitable if you want to hold some game state data in there, as the renderTexture content can be lost by GPU/Driver on some events (screen resize, etc)

  • Use Graphics.CopyTexture(). This happens entirely on GPU, but you will not be able to read pixels to the CPU from this texture, nor call Apply() after other modifications - the GPU memory will be overwritten by outdated content. If you really need to read back the pixels at some time (eg. I do it when I do the savegame) You can do:

  • This:

                   bool[] data = new bool[ra.width * ra.height];
     
                     // Copying the m_revealedArea to itself using temporary RT
                     // m_revealedArea is filled by Graphics.CopyTexture() which only affects GPU memory. GetPixels32() would not return the actual content.
                     // Blitting the m_revealedArea to the tempRT allows us to do ReadPixels() in the other direction and finally alling the GetPixels32()
                     var tempRT = RenderTexture.GetTemporary(m_revealedArea.width, m_revealedArea.height, 0, RenderTextureFormat.ARGB32);
                     try
                     {
                         Graphics.Blit(m_revealedArea, tempRT);
                         RenderTexture.active = tempRT;
                         m_revealedArea.ReadPixels(new Rect(0, 0, tempRT.width, tempRT.height), 0, 0);
                         m_revealedArea.Apply();
                     }
                     finally
                     {
                         RenderTexture.ReleaseTemporary(tempRT);
                     }
     
                     Color32[] color = m_revealedArea.GetPixels32();
     
    
    
    
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

14 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Texture2D saves as PNG correctly but doesn't display properly in RawImage 1 Answer

Taking Non Power of Two Resolution Screen Shots 0 Answers

Call camera.Render() twice: RenderTexture contents differs from ReadPixels() 1 Answer

How can I save the Bild from a Camera, which not main camera is. 1 Answer

Get RenderTexture 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges