Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 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
4
Question by yangguo · Jul 06, 2015 at 05:43 PM · texture2dpluginrendertexture

Pass a RenderTexture to a plugin with zero copies

I have camera that renders to a RenderTexture. I would like to pass the contents of the RenderTexture to a native plugin. From the Unity's native plugin example, a native plugin can only handle ID3D11Texture2D pointers which correspond to Unity's Texture2D.GetNativeTexturePtr objects. Therefore, I have a functional version whereby the RenderTexture's output is first copied to a Texture2D with ReadPixels:

     private IEnumerator DoEveryFrame()
     {
         //Wait for graphics to render
         yield return new WaitForEndOfFrame();
 
         // Remember current render textures
         RenderTexture currentActiveRT = RenderTexture.active;
         RenderTexture currentCamRT = cam.targetTexture;
 
         // Force rendering of the camera to my render texture
         cam.targetTexture = rt;
         cam.Render(); // 2nd Render seems to be necessary, but why??
         cam.targetTexture = currentCamRT;
 
         // Get a copy of the rendered data
         RenderTexture.active = rt;
         screenShot.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
         screenShot.Apply(); // hits perf significantly but needed otherwise actual copy does not occur
         
         // Restorie previously assigned render texture
         RenderTexture.active = currentActiveRT; 
         //Destroy(rt);
 
         // Issue a plugin event with arbitrary integer identifier.
            // The plugin can distinguish between different
         // things it needs to do based on this ID.
         // For our simple plugin, it does not matter which ID we pass here.
         GL.IssuePluginEvent (200); 
 
 
     }

Unfortunately, this method of using ReadPixels() and then Apply() significantly hurts performance. I don't actually need the contents of RenderTexture on the CPU. How can I accomplish either of the following:

  1. [Preferred] Pass a valid reference to the RenderTexture directly to the native plugin without any data copying. This would be ideal. However, using RenderTexture.GetNativeTexturePtr resulted in all-black texture as seen by native plugin.

  2. Make a GPU-to-GPU copy of Render Texture to Texture2D. A copy is still involved, but at least it is not crossing the bus.

My second minor question is why do I need to perform a second Camera.Render()? Why doesn't this work:

 RenterTexture.active = cam.targetTexture;
 screenShot.ReadPixels(...);
 screenShot.Apply();


This must be doable; I'm just missing the magic invocation... :-)

Comment
Add comment · Show 5
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 yangguo · Jul 15, 2015 at 04:04 PM 0
Share

Is there anyone that can help with this? Seems like zero copy ought to be something that can be done...

avatar image Shotgunbunny · Jul 20, 2015 at 02:57 PM 1
Share

Have you made any progress with this? It seems we're trying to do the exact same thing. $$anonymous$$y C# is practically identical to yours and I'm currently trying to write a C++ plugin to do #2 (RenderTexture to Texture2D). However, casting RenderTexture to ID3D11Texture2D crashes my plugin.

avatar image yangguo · Jul 21, 2015 at 03:39 PM 0
Share

Yes, I was able to pass a rt.GetNativeTexturePtr directly and it works. However, it seems I still must invoke the ReadPixels and Apply calls:

         // Get a copy of the rendered data
          RenderTexture.active = rt;
          screenShot.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
          screenShot.Apply(); // hits perf significantly but needed otherwise actual copy does not occur
          

otherwise the rt does not actually get filled with the new data! This is very confusing and kills performance...

avatar image jimfleming · Aug 06, 2015 at 08:06 PM 0
Share

yangguo, did you figure this out? I'm looking at using GetNativeTexturePtr as well.

avatar image Tracy-Ma · Sep 28, 2015 at 09:28 AM 0
Share

I got the same problem too, have you got a solution?

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Schick · Aug 18, 2015 at 08:30 AM

Did you try to switch to OpenGL (on Windows with -force-opengl). I can use the OpenGL texture in my native C++ plugin.

At the moment I am struggling with Android. Same code as on Windows but black texture as well (no OpenGL errors). Maybe the Direct3D and Android OpenGL ES 2.0 are somehow related? Did you find a solution yet?

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 DuFFOwNz · Aug 22, 2015 at 01:10 AM 0
Share

Could you post some example code? $$anonymous$$aybe from the C++ plugin as well? I am also trying to get this working in OpenGL by passing RenderTexture.GetNativeTexturePtr, but have only seen a black screen so far.

avatar image
0

Answer by Paulius-Liekis · Jul 22, 2015 at 12:06 PM

If you want to grab screen contents I think you can do this:

 RenterTexture.active = null;
 screenShot.ReadPixels(...);
 screenShot.Apply();

Because what you're doing right now is rendering to rt first and then grabbing, when you can grab from screen directly.

Comment
Add comment · Show 3 · 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 yangguo · Jul 22, 2015 at 09:22 PM 0
Share

Paul: your solution works, but is too slow for me. I am trying to avoid ReadPixels() and Apply() since these transfer data to CPU. I want to keep all data on GPU and let the plugin work on the data in the GPU

avatar image Dave-Carlile · Jul 22, 2015 at 09:32 PM 0
Share

What does your plugin do? I don't believe it's possible to work with data directly on the GPU except in a shader.

avatar image yangguo · Jul 23, 2015 at 01:13 PM 0
Share

The goal of the plugin is to pass the render texture to $$anonymous$$edia Foundation for further processing.

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

8 People are following this question.

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

Related Questions

Using Texture2DArray as RenderTarget and passing data to fragment shader 2 Answers

blending colors on a texture: shader, render texture, or other 2 Answers

Why is my RenderTexture coming out distorted? 0 Answers

Render Texture does not work on only IOS devices 0 Answers

RenderTexture to Texture2D 4 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