• 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 Double-V · Jul 31, 2020 at 07:27 PM · performanceoptimizationtexture2d

Is operating using GetRawTextureData faster that doing SetPixel/Pixels?

I'm writing a Texture2D manipulation script and I wonder if switc$$anonymous$$ng the way of doing t$$anonymous$$ns would make it faster - does using the NativeArray that you get from GetRawTextureData give a performance advantage vs just Getting and Setting pixels?

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

2 Replies

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

Answer by Kaart · Jul 31, 2020 at 10:50 PM

I was curious myself and wrote a small program to test t$$anonymous$$s. W$$anonymous$$le I'm not really familiar with RawTextureData it doesn't seem to be much slower or faster than Texture2D.GetPixels() and Texture2D.SetPixels(). However Texture2D.GetPixel(x,y) and Texture2D.SetPixel(x, y) is much slower when you need to manipulate multiple pixels.

I used a 1000x1000 .png image to test with the following import settings: alt text

I did a few runs and t$$anonymous$$s would be a typical result: alt text

I've included the script I used if you want to do further testing, I'm really interested in your results. using System.Diagnostics; using UnityEngine;

 public class Example : MonoBehaviour
 {
     [SerializeField]
     private Texture2D _image;
 
     private Stopwatch _stopwatch = new Stopwatch();
 
     // Start is called before the first frame update
     void Start()
     {
         if (_image != null)
         {
             TestGetSetPixel();
             TestGetSetPixels();
             TestRawTextureData();
         }
     }
 
     private void TestGetSetPixel()
     {
         _stopwatch.Start();
 
         for (int y = 0; y < _image.height; y++)
         {
             for (int x = 0; x < _image.width; x++)
             {
                 Color color = _image.GetPixel(x, y);
 
                 // Do somet$$anonymous$$ng fancy with the color value.        
                 color = new Color(0f, 0f, 0f);
                 _image.SetPixel(x, y, color);
             }
         }
 
         _stopwatch.Stop();
         UnityEngine.Debug.Log("TestGetSetPixel took: " + _stopwatch.ElapsedMilliseconds + " milliseconds to complete.");
         _stopwatch.Reset();
     }
 
     private void TestGetSetPixels()
     {
         _stopwatch.Start();
         Color[] colors = _image.GetPixels();
 
         for (int i = 0; i < colors.Length; i++)
         {
             // Do somet$$anonymous$$ng fancy with the color value.            
             colors[i] = new Color(0f, 0f, 0f);
         }
         _image.SetPixels(colors);
 
         _stopwatch.Stop();
         UnityEngine.Debug.Log("TestGetSetPixels took: " + _stopwatch.ElapsedMilliseconds + " milliseconds to complete.");
         _stopwatch.Reset();
     }
 
     private void TestRawTextureData()
     {
         _stopwatch.Start();
         Unity.Collections.NativeArray<Color32> colors = _image.GetRawTextureData<Color32>();
 
         for (int i = 0; i < colors.Length; i++)
         {
             colors[i] = new Color32(0, 0, 0, 255);
         }
         _image.Apply();
 
         _stopwatch.Stop();
         UnityEngine.Debug.Log("TestRawTextureData took: " + _stopwatch.ElapsedMilliseconds + " to complete.");
         _stopwatch.Reset();
     }
 }
 

square1000.png (35.8 kB)
result.png (15.2 kB)
Comment
Add comment · Show 2 · 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 Double-V · Aug 01, 2020 at 12:23 PM 0
Share

So in my implementation I'm blurring an image, so I do need to make changes per individual pixel and it turns out that yes, when there are hundreds/thousands of those then setting individual bytes in the NativeArray is faster than doing GetPixel, SetPixel. In my case I had a texture with TextureFormat.RGB24, which means there are 3 array elements per color, but I think it would still be faster even with RGB32.

The exact values probably have a lot to do with other stuff in the implementation, but the SetPixel GetPixel one took around 3050ms on a 1600x800 texture and around 2000ms with GetRawTextureData(), with the same resolution and other settings of the blur.

avatar image Kaart Double-V · Aug 01, 2020 at 03:32 PM 1
Share

Please note there is a difference between Texture2D.GetPixel()/SetPixel() and Texture2D.GetPixels()/SetPixels(). The later uses a Color array which is much faster than getting and setting each individual pixel colors using GetPixel()/SetPixel().

avatar image
0

Answer by joshrs926 · Feb 07, 2022 at 07:43 PM

Yes it can be a lot faster depending on a few t$$anonymous$$ngs. First you need to know exactly what format Unity has stored the pixels. For example they might be stored as RGBA32 w$$anonymous$$ch means each pixel is 4 bytes, 1 byte per channel or it might be stored as RGB24 w$$anonymous$$ch is similar but without the alpha so it is 3 bytes per pixel. Also you'd be getting/setting bytes not floats so a float value of .5f would probably be rougly a byte value of 128. You'd have to do that conversion. Using GetRawTextureData I t$$anonymous$$nk will also avoid some copying of data back and forth. The big speedup up you can get is using the Job system with burst and multithreading to manipulate that data. You have to provide a job with a NativeArray (or some other Native Collection). If you aren't sure about the data format you could actually use GetPixels to get a Color[] and then create a NativeArray from it and give that to the job too. T$$anonymous$$s would involve multiply copies but might be faster than manipulating the data outside a bursted job. Coverting code to Bursted Jobs can give orders of magnitude speed ups.

Comment
Add comment · 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

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

161 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

Related Questions

measuring performance on android 0 Answers

General programming question on Static Classes 1 Answer

Performance issues with mesh processing 1 Answer

Draw Call Optimization 3 Answers

Improving script performance 1 Answer


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