- Home /
Displaying 2d graphics (sprites) on Android with ETC and alpha channel
We are currently porting a iPad game to unity android that uses a lot of textures to display 2d sprites. We have to minimize the texture size as much as possible.
The unity documentation recommends to use ETC compression for Android devices. It further recommends to seperate the alpha information as ETC1 does not support alpha.
So my guess in our case to create a ETC texture and a alpha texture from our PNG gfx files. Should i copy the files and use 2 different Output Formats? I.e. copy enemy.png to enemy_alpha.png and ouput one in ETC format and one in Alpha 8-Bit format?
The next question would be how to combine those textures while rendering. I guess a special shader would be needed for that?
Currently we are using a simple shader that looks like this:
Shader "2D Android" {
Properties {_MainTex ("Texture (A = Transparency)", 2D) = ""}
SubShader {
Tags {Queue = Transparent}
Ztest Always
Zwrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass {SetTexture[_MainTex]}
}
}
If your sprites are characters or anything significant you likely won't want to use any compression at all. $$anonymous$$obile compressions are great for saving space but they do a number on the quality.
Hey equalsequals, thanks for your comment. But i have to do compression of some sort. The quality seems to be okay so far.
I am now one step further. I created a separate alpha mask texture by copying as i suggest to myself using (alpha 8) as compression setting.
Then i modified the shader like this:
Shader "Android Alpha" {
Properties {
_$$anonymous$$ainTex ("Texture (A = Transparency)", 2D) = ""
_Alpha$$anonymous$$ap ("Texture (A = Transparency)", 2D) = ""
}
SubShader {
Tags {Queue = Transparent}
Ztest Always
Zwrite Off
Blend SrcAlpha One$$anonymous$$inusSrcAlpha
Pass {
SetTexture[_$$anonymous$$ainTex]
SetTexture[_Alpha$$anonymous$$ap] {
combine previous, texture
}
}
}
}
The problem is that using a "uncompressed" 8-bit alpha texture for each texture will consume too much memory.
In example a ETC compressed texture of 2048x2048 size will consume 1 megabyte memory. The 8-bit alpha will consume 4 megabytes of memory. So i will end up with 5 megabytes for a 2048x2048 texture.
At some android development site i found the information that you can store the alpha channel information in one of the rgb components of another ETC compressed texture. Is it possible to write a shader that uses i.e. the r-channel data as alpha-channel data?
Answer by equalsequals · Jul 05, 2011 at 02:30 PM
Hey Andreas,
That was exactly what I was going to suggest you do in this case. So with that said, you asked how you'd take the red channel from an image and use just that data as an alpha mask for another RGB texture.
One hitch in this is that I can't think of how to do this with the fixed-function pipeline, at least with any amount of ease, which means you would likely have to employ the programmable pipeline which is only available from OpenGLES 2.0 onward.
If that is okay, here is a working cg shader:
Shader "==/Alpha Red"
{
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Mask ("Mask", 2D) = "white" {}
}
SubShader
{
Tags
{
"RenderType"="Transparent"
"Queue" = "Transparent"
}
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
Ztest Always
Zwrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _Mask;
float4 _MainTex_ST;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
return o;
}
half4 frag(v2f i) : COLOR
{
float4 MainTex = tex2D(_MainTex,(i.uv.xyxy).xy);
float4 Mask = tex2D(_Mask,(i.uv.xyxy).xy);
//assemble the RGB from _MainTex with the splatted channel from _Mask
//Note that XYZW is equivalent to RGBA so Mask.x is effectively Mask.r, change as needed.
float4 MaskedTex = float4(MainTex.x, MainTex.y, MainTex.z, Mask.x);
return MaskedTex;
}
#ENDCG
}
}
FallBack "Diffuse"}
(Sorry about the formatting, I really hate it here.)
Hope that helps.
==
Hey...I tried your shader code and it works. I tested it on 2 different Android Devices (HTC desire and SE XPeria Play). Thanks a lot.
Your answer
Follow this Question
Related Questions
Combine two ETC textures with custom shader (one with alpha) 1 Answer
Particles with the "Mobile/Particles/Alpha blended" look very dark on Nexus 4 0 Answers
Color To Alpha shader for android not working 0 Answers
Alpha problem with textures on a plane 2 Answers
sprite.associatedAlphaSplitTexture with RGB Crunched ETC1 0 Answers