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
1
Question by Lesnikus5 · Feb 24, 2021 at 03:49 PM · texturearraytexture2dserializationnative

Why is NativeArray always shorter than the number of pixels in the texture?


I am trying to serialize a 512х512 texture into bytes for saving to file using GetRawTextureData, because this way will not generate garbage.. But I am getting error.


IndexOutOfRangeException: Index 87381 is out of range of '87381' Length. Unity.Collections.NativeArray`1[T].FailOutOfRangeError (System.Int32 index) (at :0) Unity.Collections.NativeArray`1[T].CheckElementReadAccess (System.Int32 index) (at :0) Unity.Collections.NativeArray`1[T].get_Item (System.Int32 index) (at :0)


I don't understand why the native array is less than the number of pixels in the texture. Why the length is 87381, because my texture has the number of pixels 512x512=262144. How do I get this to work?

     NativeArray<Color> data;
     byte[] byteArray = new byte[262144];
     byte layer = 0;
 
     void Save() //not work
     {
         data = tex.GetRawTextureData<Color>();
         int index = 0;

         for (int y = 0; y < tex.height; y++)
         {
             for (int x = 0; x < tex.width; x++)
             {
                 if (data[index].r == 1) // **ERROR THIS LINE**
                 {
                     layer = 0;
                 }
                 else if (data[index].g == 1)
                 {
                     layer = 1;
                 }
                 else if (data[index].b == 1)
                 {
                     layer = 2;
                 }
                 else if (data[index].a == 1)
                 {
                     layer = 3;
                 }

                 byteArray[index] = layer;
                 index++;
             }
         }

         File.WriteAllBytes(Application.persistentDataPath + "/byteArray_" + i.ToString() + ".byte", byteArray);
     }


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
3
Best Answer

Answer by andrew-lukasik · Feb 24, 2021 at 06:52 PM

Short answer

 byte[] byteArray = null;
 var rawDataPtr = texture.GetRawTextureData<byte>();
 
 // method #1
 byteArray = rawDataPtr.ToArray();
 
 // method #2
 if( byteArray==null || byteArray.Length!=rawDataPtr.Length ) byteArray = new byte[ rawDataPtr.Length ];
 rawDataPtr.CopyTo( byteArray );

Longer answer, a byte

"RawTextureData" in GetRawTextureData means this data is what your GPU receives.

(Spoiler alert) It's rarely Color[] i.e. 16 bytes/pixel.


Depending on it's TextureFormat, this very well may be just compressed byte[] - polar opposite of easy to understand & uncompressed Color[] you expect it to be - thus breaking easily predictable relation between array size and number of pixels.


Valid <T> in GetRawTextureData<T>, for uncompressed textures, can be chosen depending on texture.format property:

  • TextureFormat.Alpha8 - <byte>

  • TextureFormat.R8 - <byte>

  • TextureFormat.R16 - <ushort>,<byte2>

  • TextureFormat.RHalf - <half>,<byte2>

  • TextureFormat.RFloat - <float>,<byte4>

  • TextureFormat.RGB24 - <byte3>

  • TextureFormat.RGBA32 - <Color32>,<byte4>

  • TextureFormat.RGBAHalf - <half4>,<byte2x4>

  • TextureFormat.RGBAFloat - <Color>,<Vector4>,<float4>,<byte4x4>

so number of pixels and array length will match perfectly.


Bestiary:

public struct byte2 { public byte x, y; }

public struct byte3 { public byte x, y, z; }

public struct byte4 { public byte x, y, z, w; }

public struct byte2x4 { public byte2 c0, c1, c2, c3; }

public struct byte4x4 { public byte4 c0, c1, c2, c3; }


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 andrew-lukasik · Feb 24, 2021 at 08:53 PM 0
Share

In my guess-timation what has happened in your particular case was:

(512*512) * 4 / (4*3) = 87381.33333


Translation: texture data was 4 bytes/pixel ( RGBA32 most likely) and was cast into ill-fitting byte4x3 struct ( float3 or int3) only to finally end up as Color struct with 0 alpha. After rounding down the resulting pixel count to an integer it gives you exactly 87381.

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

163 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 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

PackTextures Horizontally? (1 Row) or Alternative Method 1 Answer

Array of arrays of Textures 2 Answers

Can Unity utilize textures created by a plugin? 1 Answer

Making an array for Texture2D?? 2 Answers

can texture2D and GameObject be serialized? 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