Based on your code example, it looks like you use the alpha channel in your bitmask to determine whether or not to draw a pixel. It also looks like you treat an alpha of
0 as "draw the pixel" and anything
> 0 to "not draw the pixel." I'm also going to assume that in your bitmask, you can make anti-aliased edges in the alpha channel where the alpha value is between
1 (exclusive). If any of these assumptions are incorrect let me know.
Now, assuming the above is true, you should be able to do this simply by using this code:
float4 tex = tex2D(sprite, texCoord);
float4 bitMask = tex2D(mask, texCoord);
return float4(tex.b,tex.g,tex.r,1 - bitMask.a);
float4(0,0,0,0);is actually drawing a black pixel to the screen but since the alpha channel is set to
0, it's transparent. So, rather than drawing a black pixel, we'll continue to draw the regular pixel colour and just change the alpha channel on it. By using
1 - bitMask.a, we're saying "when the bitmask alpha == 1, don't draw the pixel". This is what you were already doing with
if (bitMask.a >0). However, if the value is less than
1, but not
0 we still draw the pixel, it will just be semi-transparent. Likewise, if the value is equal to
0, it will fully draw the pixel.
Hope this helps!
How is the bitmask generated? I think it would be easier and more efficient to pre-calculate the different alpha values in the bitmask texture rather than dealing with edge detection in the shader. If you really want to do it in the shader, you could try sampling pixels within a certain distance from the current one (if the current one is not "blocked" (i.e.
bitmask.alpha == 1) to see if they are blocked. And then, based on whichever blocked pixel is closest, you could set the alpha value based on the distance away.
For example, let's say you start by going up pixel by pixel for a maximum of 5 pixels or until you hit a blocked one. Then you would do the same thing for the right, down and left directions and possibly on the diagonals as well. After you do that, we'll say the closest blocked pixel is 2 pixels away. So the alpha is
2/5 == 0.4 (
2 being the pixel distances and
5 being the max distance checked).
In this way, if a pixel is 1 pixel away from a blocked pixel, it will have
0.2 alpha (
1/5 == 0.2) and will be mostly invisible.