Getting Smooth Edged for Alpha Erosion for Masked?

Hi Guys, I was wondering if anyone have any good tips in getting smoother edges alpha erosion(threshold) for masked materials.
Currently I find I get a lot of crunchy edges when doing masked. Would the only way to get smoother animation be only up resing the texture. The current texture here is a 512x512 and I’m currently using Unreal 4 with this

1 Like

try another compression. if its just a grayscale texture set it to alpha.
Only thing that comes to mind atm.

I never really seem to have this problem truth be told.

Yeah currently its compression is set to Alpha. Thanks anyways

ok seems like one option I could have done is just blurring the texture even more seems to have solved it

Blur, alpha only format, and pay with contrast to get more range. I’ll sometimes do my alpha textures in 16bit so I can muck around with the curves with out losing precision in the final 8bit alpha.

It might also be worth using a sharpened alpha blend instead of alphatest if you don’t need the ZWrite. Or even alpha to coverage (though I don’t think UE4 has added support for that still).

(alpha - _cutoff) / max(0.0001, fwidth(alpha)) + 0.5


I did something like that before, a fake smooth occuring after the erosion.
Here is the idea :
N : is you actual frame
nG defines the actual value in your texture at frame N;
To have cheap smooth, i basically evalute previous and next frame. using a smooth step value.

so if my smooth step is 1 I evaluate N and N+1 and N-1.
The range of the smooth can be set using a parameter that I called smoothLength which determine the grayscale value between 2 frames.

so at the and I have :

FinalFrame = erosion(nG);
for(int i=0; i<smoothSteps; i++){
FinalFrame += erosion(nG - i * smoothLength);
FinalFrame += erosion(nG + i * smoothLength);
//get back finalFrame values between [0;1] :
FinalFrame = FinaleFrame / (smoothSteps*2 + 1);

To be a little bit clearer erosion() is here the function you’re actually using to get the actual result you have,
its parameter is the actual grayscale value you’re looking for.

So the result is you’ll get back a grayscale but it smoothness and falloff will be defined by smoothSteps and smoothLength respectively.

The smooth is cheaper that most of smoothing algorithm as it is not based on convolution matrix looking one by one each pixel, and its neighbours to findout the new value of your actual pixel. the idea is almost the same, but it looks at a group of pixels.
By testing it in multiple occasion I can tell that in most of situation smoothstep = 5 and smoothlength = 0.1, is sufficient :slight_smile:

1 Like

You’re describing spatial super sampling here. But what you’re doing in the code is temporal super sampling, aka motion blur, with a fixed time step. If the erosion() function is sampling the same texture position regardless of the input, then this is more expensive than my fwidth() example, or using smoothstep(), and less effective. If the texture position changes based on the input than this is no more efficient than the the method you’re comparing against, but again it is potentially less effective.

If this is an effect that’s going to be happening fast, this technique can look visually better than my fwidth example, but worse than a straight smoothstep() with similar width.

Ultimately the smoothness of the edge is still limited by the quality of the texture asset, and the blend mode used (masked vs alpha blended). Your technique won’t help here any more than the other techniques if the original texture has noise or block compression artifacts.