Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 wok33 · Jul 17, 2018 at 02:15 PM · renderingfile-ioreadpixels

Optimize saving render buffer to file

I have found a lot of questions and answers on this topic, but no complete recommended way to do this. We are rendering HD frames and want to save them to disk in raw format (i.e. not JPEG or PNG) at 60FPS. right now we are getting around 8FPS with the following code:

 IEnumerator RecordFrame()
     {
         yield return new WaitForEndOfFrame();
 
         var renderTexture = new RenderTexture(Screen.width, Screen.height, 32, RenderTextureFormat.ARGB32);
         cam.targetTexture = renderTexture;
         cam.Render();
         cam.targetTexture = null;
 
         RenderTexture.active = renderTexture;
         Texture2D screenshot = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBA32, false);
         screenshot.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
         screenshot.Apply();
         RenderTexture.active = null;
               
         String path = "Screenshot_" + m_num + ".bin";
         byte[] bytes = screenshot.GetRawTextureData();
         File.WriteAllBytes(path, bytes);
         m_num++;
     }
 
     public void LateUpdate()
     {
         StartCoroutine(RecordFrame());
     }

From past posts it seems that ReadPixels is the culprit, and needs optimization. I am trying glReadPixels but it returns a black frame, like the one in this post: https://answers.unity.com/questions/1251855/glreadpixels-in-unity-5-always-get-black-frame.html

Is there a definitive answer to this question? Or any asset in the store that can achieve this functionality out of the box?

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

1 Reply

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

Answer by wok33 · Jul 19, 2018 at 09:51 AM

I ended up using the solution from here: https://github.com/keijiro/AsyncCaptureTest I get ~40 FPS for HD resolution, main bottleneck seems to be the write to disk function which blocks Update().

For future reference, with unity 2018.2:

 public class AsyncCapture : MonoBehaviour
 {
     Queue<AsyncGPUReadbackRequest> _requests = new Queue<AsyncGPUReadbackRequest>();
     int m_num = 0;
   
     void Update()
     {
         while (_requests.Count > 0)
         {
             var req = _requests.Peek();
   
             if (req.hasError)
             {
                 Debug.Log("GPU readback error detected.");
                 _requests.Dequeue();
             }
             else if (req.done)
             {
                 var data = req.GetData<byte>().ToArray(); // request bytes so that they are directly writeable to the file
                 string filename = "Screenshot_" + m_num + ".raw";
                 using (BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Create)))
                 {
                     writer.Write(data);
                 }
                 m_num++;
                 _requests.Dequeue();
             }
             else
             {
                 break;
             }
         }
     }
      
     void OnRenderImage(RenderTexture source, RenderTexture destination)
     {
         if (_requests.Count < 8)
             _requests.Enqueue(AsyncGPUReadback.Request(source));
         else
             Debug.Log("Too many requests.");
   
         Graphics.Blit(source, destination);
     }
 }
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 Kibsgaard · Jul 19, 2018 at 09:09 PM 0
Share

Cool. Thanks for the code example. If you want to save a video to disc, you can also take a look at https://stackoverflow.com/questions/44865782/how-to-record-the-screen-in-unity-and-make-output-as-a-file. There's also lots of tools on the asset store that can help. For example the free https://assetstore.unity.com/packages/tools/video/video-capture-75653 (I haven't tried it, but it looks promising). I think you might run into throughput problems if you try to save 60 uncompressed full frames directly to disc; even if you make it multithreaded (~475 megabytes per second is more than most SSDs can handle).

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

93 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 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 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 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 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 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

glreadpixel without canvas 0 Answers

How do I get the raw pixels of a RFloat RenderTexture on the CPU? 5 Answers

Rendering an HD PNG off-screen? 0 Answers

ReadPixels Overlaying Opacity 0 Answers

iOS: Specify Top Level Texture Mipmap 0 Answers


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