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

Dynamically created Texture is saved with wrong resolution

Discussion in 'Scripting' started by Piflik, Jun 14, 2019.

  1. Piflik

    Piflik

    Joined:
    Sep 11, 2011
    Posts:
    291
    I have a rather curious problem. I am creating a Texture2D object programmatically and then I want to save it as an .exr file. The file contains Vertex Deformation data that I then pass to a shader in order to dynamically deform a mesh using the vertex shader. I have an importer that reads meshdata and calculates deformations for each vertex in each frame. This data is then passed to a function that creates a texture from it.

    The Texture2D gets created with the correct size (315x315), but when I encode it to .exr, the resulting file has a smaller resolution (256x256). Interestingly, with a larger object (more vertices) it works correctly and both the Texture2D object and the file have the same resolution (1127x1127).

    This is the code I use to save the file:

    Code (CSharp):
    1. private static void SaveRenderTexture(RenderTexture input, int num, string fileName, bool useFloat = false) {
    2.         if (input != null) {
    3.             int width = input.width;
    4.             int height = input.height;
    5.  
    6.             Texture2D tex = new Texture2D(width, height, TextureFormat.RGBAFloat, false);
    7.  
    8.             Graphics.SetRenderTarget(input);
    9.             tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
    10.             tex.Apply();
    11.  
    12.             string path = $"Assets/Resources/{fileName}/";
    13.             if (!Directory.Exists(path))
    14.                 Directory.CreateDirectory(path);
    15.  
    16.             // Encode texture into the EXR
    17.             Texture2D.EXRFlags flags = Texture2D.EXRFlags.None;
    18.             if (useFloat) flags |= Texture2D.EXRFlags.OutputAsFloat;
    19.             byte[] bytes = tex.EncodeToEXR(flags);
    20.             File.WriteAllBytes($"{path}{fileName}_{num}.exr", bytes);
    21.  
    22.             UnityEngine.Object.DestroyImmediate(tex);
    23.         }
    24.     }
    Does anyone have an idea why this could be happening? Are .exr files below a certain size restricted to POT?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    Hm, just did this test and it produced what Apple tells me is a 315x315 EXR file.

    This is my code:

    Code (csharp):
    1.  
    2.     void Start () {
    3.         Texture2D foo = new Texture2D( 315, 315, TextureFormat.RGBAFloat, false);
    4.  
    5.         Debug.Log( "Size:" + foo.width + " x " + foo.height);
    6.  
    7.         var exr = foo.EncodeToEXR(Texture2D.EXRFlags.None);
    8.  
    9.         System.IO.File.WriteAllBytes( "gnord.exr", exr);
    10.     }
    And this is what Apple says with Command-I (info), which is 315x315 as coded above:

    gnord.png

    That is with Unity 2017.4.2, the one I happened to have fired up at the moment.

    Maybe try some more experimenting with sizes or options?
     
  3. Piflik

    Piflik

    Joined:
    Sep 11, 2011
    Posts:
    291
    Ok, I am stupid. I just now realized that the files themselves are fine, but Unity imports them as POT. And there is a setting to disable that. I never even consciously noticed that option because I usually don't work with non-POT textures.
     
    Kurt-Dekker likes this.