Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Unity Docs Example not working... Help please!

Discussion in 'Scripting' started by callen, Feb 18, 2017.

  1. callen

    callen

    Joined:
    Dec 31, 2013
    Posts:
    31
    I'm trying to figure out how to make a readable texture copy of a texture. Luckily for me, Unity had an article about accomplishing exactly this.

    https://support.unity3d.com/hc/en-u...How-can-I-get-pixels-from-unreadable-textures

    So I encapsulated that code into a method: Texture2D copyTexture(Texture2D source), a line-for-line copy of the example code.

    However, after the operation runs, I get a texture returned that is the same size as my input, but seemingly only contains the bottom-left corner of pixel data from my source. The results look stretched in a non-uniform way as well.

    I already learned that I need to call that at a certain time, so I'm using a Coroutine with a WaitForEndOfFrame(), which fixed error being thrown and got me to where I am now.

    I'm using a sprite as my source, but since it isn't packed at all and doesn't have any weird properties set, I figured that using sprite.texture was enough. Maybe that's wrong? But I don't know why.

    Anyone who's more familiar with RenderTextures and/or Graphics.Blit than I am, please give me some advice! I've been struggling with this for 24 hrs now and no idea what more to try.

    Thank you so much anyone who can help!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    Hm, I tried it and it just works. I'll attach my code here, you can stick it on a gameObject, supply the OriginalTexture property with a non-read-only texture, and this copies it, then puts a white stripe across it to prove it is read-write-able.

    Finally OnGUI draws it in the upper left corner. There is something glitchy at the right edge of the image, but it might be due to some limitation of RenderTextures being a multiple of 8, 16 or 32 pixels, but I'm just speculating. Basically it works.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class RTTRendering : MonoBehaviour
    5. {
    6.     // copied from: https://support.unity3d.com/hc/en-us/articles/206486626-How-can-I-get-pixels-from-unreadable-textures
    7.     Texture2D CreateReadWriteCopy( Texture2D texture)
    8.     {
    9.         // Create a temporary RenderTexture of the same size as the texture
    10.         RenderTexture tmp = RenderTexture.GetTemporary(
    11.                                                       texture.width,
    12.                                                       texture.height,
    13.                                                       0,
    14.                                                       RenderTextureFormat.Default,
    15.                                                       RenderTextureReadWrite.Linear);
    16.      
    17.         // Blit the pixels on texture to the RenderTexture
    18.         Graphics.Blit(texture, tmp);
    19.         // Backup the currently set RenderTexture
    20.         RenderTexture previous = RenderTexture.active;
    21.         // Set the current RenderTexture to the temporary one we created
    22.         RenderTexture.active = tmp;
    23.         // Create a new readable Texture2D to copy the pixels to it
    24.         Texture2D myTexture2D = new Texture2D(texture.width, texture.height);
    25.         // Copy the pixels from the RenderTexture to the new Texture
    26.         myTexture2D.ReadPixels(new Rect(0, 0, tmp.width, tmp.height), 0, 0);
    27.         myTexture2D.Apply();
    28.         // Reset the active RenderTexture
    29.         RenderTexture.active = previous;
    30.         // Release the temporary RenderTexture
    31.         RenderTexture.ReleaseTemporary(tmp);
    32.      
    33.         // "myTexture2D" now has the same pixels from "texture" and it's read/write
    34.         return myTexture2D;
    35.     }
    36.  
    37.     public Texture2D OriginalTexture;
    38.  
    39.     Texture2D CopiedTexture;
    40.  
    41.     void Start()
    42.     {
    43.         CopiedTexture = CreateReadWriteCopy (OriginalTexture);
    44.  
    45.         for (int x = 0; x < CopiedTexture.width; x++)
    46.         {
    47.             int y = (x * CopiedTexture.height) / CopiedTexture.width;
    48.             CopiedTexture.SetPixel( x, y, Color.white);
    49.         }
    50.         CopiedTexture.Apply ();
    51.     }
    52.  
    53.     void OnGUI()
    54.     {
    55.         int nominalPixelSize = 400;
    56.         Rect r = new Rect(
    57.             0, 0, nominalPixelSize, (CopiedTexture.height * nominalPixelSize) / CopiedTexture.width);
    58.         GUI.DrawTexture (r, CopiedTexture);
    59.     }
    60. }
     
  3. callen

    callen

    Joined:
    Dec 31, 2013
    Posts:
    31
    Thanks for the reply it's helped a lot.

    Your code didn't work for me either, but then I realized that it was at least in part due to my being in Unity 4.6 - in the latest versions it's working properly. However I'm trying to make a 4.6-compatible asset store package so I'll need to figure out what's going wrong in that version :(

    Thanks for the help, maybe I can find something in the version notes that can help me.