Page 1 of 2

Using transparent images as TextureSource (Unity)

Posted: 17 Oct 2013, 10:16
by ai_enabled
After release of the NoesisGUI 1.1 we was very happy to start using the TextureSource feature. But it has issue with the tranparent textures:
Screenshot at 2013-10-17 15 04 12.png
Screenshot at 2013-10-17 15 04 12.png (5.82 KiB) Viewed 11442 times
We asked the NoesisGUI team about it and they respond kindly:
"We have been investigating this issue and found an explanation. Problem is that Unity doesn't use premultiply alpha (blogs.msdn.com/b/shawnhar/archive/2009/11/06/premultiplied-alpha.aspx) and NoesisGUI pipeline is entirely based in premultiply alpha. Premultiply alpha is the correct way to do the things.
Ideally the conversion from straight alpha to premultiplied alpha should be done at texture import time (as we do in Noesis), but there is no option to active it in Unity. The solution for you is doing in by hand. You have to multiply each color channel by the alpha channel."
So, the NoesisGUI require textures in premultiplied alpha format to render it correctly. Here is the C# code of texture converter class written for our game project. We decide to open source of this converter to support the NoesisGUI community!
using UnityEngine;

public static class TextureConverter
{
		public static Texture2D ConvertToPremultipliedAlpha(Texture2D source)
		{
			Color[] srcColors = source.GetPixels();
			Color[] dstColors = new Color[srcColors.Length];
			for (int i = 0; i < srcColors.Length; i++)
			{
				Color srcColor = srcColors[i];
				float a = srcColor.a;
				dstColors[i] = new Color(srcColor.r * a, srcColor.g * a, srcColor.b * a, a);
			}

			Texture2D result = new Texture2D(source.width, source.height, TextureFormat.ARGB32, false);
			result.SetPixels(dstColors);
			result.Apply();
			return result;
		}
}
Converter usage example code (C#):
    // texture is variable representing Texture2D
    var convertedTexture = TextureConverter.ConvertToPremultipliedAlpha(texture);
    // now you can use this texture in TextureSource
    var textureSource = new TextureSource(convertedTexture);

Re: Using transparent images as TextureSource (Unity)

Posted: 17 Oct 2013, 10:19
by ai_enabled
Here is correct result image:
Screenshot at 2013-10-17 14 59 43.png
Screenshot at 2013-10-17 14 59 43.png (5.45 KiB) Viewed 11441 times

Re: Using transparent images as TextureSource (Unity)

Posted: 17 Oct 2013, 10:34
by ai_enabled
And one important note about it - if you import in the Unity Editor, please set texture type to "Advanced" and turn on checkbox "Read/write enabled":
Screenshot at 2013-10-17 15 33 01.png
Screenshot at 2013-10-17 15 33 01.png (29.07 KiB) Viewed 11437 times

Re: Using transparent images as TextureSource (Unity)

Posted: 17 Oct 2013, 11:04
by sfernandez
Great job!!
Thanks for sharing with the community!

:D

Re: Using transparent images as TextureSource (Unity)

Posted: 21 Oct 2013, 21:16
by jsantos
We are going to improve the documentation with all this and if you don't mind we are going to publish the source code to convert to premultiply-alpha in our github project: https://github.com/Noesis/noesisgui-contrib

thank!

Re: Using transparent images as TextureSource (Unity)

Posted: 22 Oct 2013, 06:39
by ai_enabled
We are going to improve the documentation with all this and if you don't mind we are going to publish the source code to convert to premultiply-alpha in our github project: https://github.com/Noesis/noesisgui-contrib
thank!
Feel free to use this source code anywhere.
Thank you for the great framework!

Re: Using transparent images as TextureSource (Unity)

Posted: 18 Jan 2017, 11:44
by tomczak
Hi there,

I've got a large amount of transparent pictures being displayed in my app, and this preprocessing stage is very heavy and slow on mobile devices.

I was able to preprocess everything, saving the Texture2D raw data so I can load it quite quickly after.

But, for now, I haven't find any way to use a "compressed" file format with preprocessed value within (eg., TIFF, PNG, etc... with already processed colors so that I can avoid the multiplication stage).

Storing uncompressed data directly in the resources is not a good solution, for my apk size increases drastically. I'm building this cache on runtime, but it requires a lot of space (up to 100 Mo) on the user device.

Have anyone find a way to preprocess the multiplication but without the need to store uncompressed picture data ?

If Noesis VNext could manage unpremultiplied alpha, it would be a wonderful time savior :)

[Edit : Some clarifications]

Re: Using transparent images as TextureSource (Unity)

Posted: 19 Jan 2017, 05:40
by jsantos
Hi!

Can't you do the premultiplication in the source image itself? (in the .PNG for example, just before Unity creates the internal texture). That way you can use compression without any kind of problem.

Problem with not using premultiply alpha is that the results are not correct. You can find more information about it in internet, but basically without premult-alpha you get halos around the edges. What I don't really understand is how Unity still doesn't support this step at import time.

http://answers.unity3d.com/questions/98 ... -pngs.html

Re: Using transparent images as TextureSource (Unity)

Posted: 20 Jan 2017, 16:29
by tomczak
Hi!

Can't you do the premultiplication in the source image itself? (in the .PNG for example, just before Unity creates the internal texture). That way you can use compression without any kind of problem.

Problem with not using premultiply alpha is that the results are not correct. You can find more information about it in internet, but basically without premult-alpha you get halos around the edges. What I don't really understand is how Unity still doesn't support this step at import time.

http://answers.unity3d.com/questions/98 ... -pngs.html
Hi !

In fact that was the first thing I tried :

* First, using Photoshop to perform the premultiplication => no success
* Then, creating an editor extension, taking a Texture2D, premultipliing it and saving it to PNG => no success

I guess the issue is related to the PNG format itself (either in terms of precision, or for its compression). And Unity can only save Texture2D as PNG, JPG, or Raw data.

With my workaround (building premultiplied cache) everything is now OK, i'm just concerned about the temp data folder size :)

Re: Using transparent images as TextureSource (Unity)

Posted: 20 Jan 2017, 19:43
by jsantos
* First, using Photoshop to perform the premultiplication => no success
What do you mean with "no success" ? Could you elaborate?