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]}
}

}

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.

==