Wednesday, 3 January 2018

Runtime texture loading and performance

Assets is something, really something. Because assets in unity project contains everything what you see, what you hear, how it works. Usually we are preparing assets outside unity and then we are adding them to UnityEditor. Then we compile project and everything is fine.

Imagine you need to load textures in runtime. You don't have prepared data in UnityEditor. You have a lot of users (players) and you want to give them a opportunity to load own textures. It's fine. It's not a big deal. In common use players are looking on the screen device (monitor, smartphone, etc.) and final state of loading picture as texture it's not very performance killer. You can feel freeze of application for a second, but perfomance affect is acceptable. Loosing few frames it's okay.

Virtual reality is something else. You need very good performance, stable framerate. Going under 100 fps usually you feel something is wrong. You can't stop the scene for a second because of loading picture as texture. The screen in VR start flashing and you will start feel dizziness.

The question is, how to load picture as texture without affecting the performance?

I was looking for a solution, but I didn't find something usefull. I tried to load pictures with different tools and ways. Best option is to process pixel colors during frames. I created a script to process colors from source picture in background thread and apply this loaded data to texture in runtime. Just skip talking and take a look on code. It's not complicated.

For obtaining pixel colors from picture in separated thread I used System.Drawing component. I just copied this dll directly from Unity installation directory (%Unity Folder%\Editor\Data\Mono\lib\mono\2.0) to %project%/Assets/Plugins and changed API compatibility in Player settings to ".NET 2.0". Of course you can change this code with your solution. You can get pixel colors how you want, just fill up custom "buffer" with pixel colors. Remember unity Color RGB values are between 0 to 1.

If you like this solution, you can support me