I had written a pixel shader a while back that masked pixels based on transparency value against a given threshold. The input texture was 32 bit. It looked cool at the time but it was masking the texture with hard edges so it did not quite have a finished look to it.

sampler ColorMapSampler;

float4 RemoveColor;

float4 PS(float4 Light: COLOR0, float2 Tex: TEXCOORD0) : COLOR

{

float4 texd = tex2D(ColorMapSampler, Tex);

texd[0] *= Light[0];

texd[1] *= Light[1];

texd[2] *= Light[2];

texd[3] *= Light[3];

if( texd[3] < RemoveColor[3] )

{

texd[0] = 0;

texd[1] = 0;

texd[2] = 0;

texd[3] = 0;

}

return texd;

}

So how to mask pixels and keeping a soft edge? Assuming that the texture alpha channel has gradients which will give a soft falloff which generally is the case, simply interpolate the alpha value down to zero with t ratio calculated over upper threshold ( R ) to lower threshold ( RL ).

sampler ColorMapSampler;

float4 RemoveColor;

// Light: External color blend where Alpha is supposed to reduce to zero over time

float4 PS(float4 Light: COLOR0, float2 Tex: TEXCOORD0) : COLOR

{

float4 texd = tex2D(ColorMapSampler, Tex);

float R = RemoveColor[3];

float A = Light[3] * texd[3];

// No effect if input threshold param set to zero

if (R <= 0.0)

{

texd[0] *= Light[0];

texd[1] *= Light[1];

texd[2] *= Light[2];

texd[3] *= Light[3];

return texd;

}

// Setting range from R to 90% of R (this percentage can be an input parameter for better control)

float RL = R * 0.90;

// If Texture Alpha is less than lower range then drop the pixel

if (A <= RL)

{

texd[0] = 0;

texd[1] = 0;

texd[2] = 0;

texd[3] = 0;

return texd;

}

// If Alpha is lower than the threshold then interpolate

if( A < R )

{

float t = ((A – RL) / (R – RL));

texd[0] = texd[0] * t * Light[0];

texd[1] = texd[1] * t * Light[1];

texd[2] = texd[2] * t * Light[2];

texd[3] = A * t;

if (t <= 0.01)

{

texd[3] = 0;

}

return texd;

}

// Normal case

texd[0] *= Light[0];

texd[1] *= Light[1];

texd[2] *= Light[2];

texd[3] *= Light[3];

return texd;

}

Here is a sample image. Nothing fancy really. The nice thing about it is that you don’t have to generate any special maps. I must say though that additional maps will give better control over transparency and perhaps masking. The shader is a quick implementation and surely code can be written much better. I just wanted to give an idea of functionality (Isn’t that typical hehe). I hope to have nicely written code next time.