Hello,
After playing with surface shaders, I found a way to make a reveal type shader for Health bars in any UI.
The way it works is simple : It multiplies the image alpha with a static mask value for the whole texture, hiding it progressively from left to right and from bottom to top, all controlled with a slider.
The slider range is UV values, from 0 to 1, so all you have to do is at runtime to specify the said sprite UVs as this value (or it would be unprecise, as 1 = whole texture is masked, 0 = none).
The shader also take into account the vertex color.
The advantage of this technique over AlphaTesting a Mask texture is obviously performance for iOS / PowerVR hardware. As mentionned numerous times in this forum and in Unity docs, AlphaTest for iOS is to be avoided at all costs (some old thread).
Shader "MaskedSprite" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
_CutoffX("CutoffX", Range(0.0,1.0)) = 1
_CutoffY("CutoffY", Range(0.0,1.0)) = 1
}
Category {
Cull off
Blend SrcAlpha OneMinusSrcAlpha
Lighting Off
Fog { Mode Off }
SubShader {
Tags {"Queue"="Transparent" "RenderType"="Transparent"}
CGPROGRAM
#pragma surface surf Unlit alpha
half4 LightingUnlit (SurfaceOutput s, half3 lightDir, half atten) {
half4 c;
c.rgb = s.Albedo;
c.a = s.Alpha;
return c;
}
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
float4 color : Color;
};
fixed _CutoffX;
fixed _CutoffY;
void surf (Input IN, inout SurfaceOutput o) {
half4 tex = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = IN.color.rgb*tex.rgb;
o.Alpha = IN.uv_MainTex.x > _CutoffX ? 0 : IN.uv_MainTex.y > _CutoffY ? 0 : IN.color.a*tex.a;
}
ENDCG
}
}
}
I bolded the important part (so you could copy paste it in your own shader).
The mask is based on a rectangular hiding, indeed.
Example : if I want to mask my health bar from right to left, I would have to put it this shader, and at runtime perform (pseudo code to gain time, but you get the idea) :
HealthBar.material.SetFloat(“_CutoffX”, HealthBar_Mesh_UV_TopRight-myValue);
If you want the hide to operate on the left side instead of right, you juste invert the comparison signs in the o.Alpha operation.
Hope it helps.