- Home /
How do I blend a transparent texture with an opaque one?
I have two RGBA32 textures from PNG files, one is opaque, the other one has opaque pixels, completely transparent pixels, and shadow pixels (black with 50% alpha. In the inspector, I can see the alpha of my transparent texture properly, I see black, white and grey.
Let's assume for argument's sake that both textures have the same resolution, say 32px * 64px. I am using:
color2 = texture2.getpixels(0,0,32,64);
texture1.setpixels(0,0,32,64,color2);
but when I render texture1 it shows texture2 only with white where the transparency (so the layer below) is supposed to be. I actually want to layer the two textures one on top of the other and use the result as one texture (including darkened parts by the "shadow" pixels.
If I set "Alpha is transparency" in the import settings, it appears even worse. The texture clamps on the pixels that should be completely transparent and the half-transparent ones appear black.
What am I doing wrong?
Answer by socialspiel · Apr 24, 2014 at 03:54 PM
Have you checked the value of color2.a?
Is texture1 the right format (ARGB32) and Read/Write enabled?
It's RGBA32. Does it make a difference? Read / write is enabled, I can render it as I said. Didn't check the alpha programmatically but it wouldn't appear in the inspector correctly in alpha mode if it weren't correct.
@socialspiel but is this the correct approach? Does set pixels "add" pixel alpha values or it just replaces?
setpixel only works on certain texture formats (rgba32 is one of them)
it completly replaces the the pixel. if you want to blend the alpha of both pixels, you have to get the pixels of texture1 too and multiply/blend the alpha values.
depending on your texture size you might want to use Graphics.Blit (https://docs.unity3d.com/Documentation/ScriptReference/Graphics.Blit.html) which is much faster and write a shader or experiment with the materials used for it
@socialspiel almost there! I wrote this up:
public Texture2D addTextures(Texture2D texture1, Texture2D texture2) {
Color[] color1 = texture1.GetPixels();
Color[] color2 = texture2.GetPixels();
for (int i = 0; i < color1.Length; i++) {
if (color2[i].a == 1) {
color1[i] = color2[i];
} else if (color2[i].a != 0) {
color1[i].a = color2[i].a;
}
}
texture1.SetPixels (color1);
return texture1;
}
Only issue is now the alpha (shadows). Tried with color1[i].a *= color2[i].a as well, nothing. Any ideas?
You are soooo close with that coding sample. You're going to want to do
Color.Lerp(color1[i], color2[i], color2[i].a);
ins$$anonymous$$d of that if statement. That will cover your transparency, shadows, opaque, etc. Thanks to you both though for helping me fix out my auto-applied watermark issue that I figured out because of your work. That Color.Lerp is the last step of the puzzle that you needed (and if you want to take it a step further, just multiply that last argument by a value between 0-1 to deter$$anonymous$$e how transparent you want it to be)
Thanks for that! I was doing something similar but was adding the colors. Worked well except for alphas.