Home > Software design >  Rendered Feathered Line Falloff Slope (math)
Rendered Feathered Line Falloff Slope (math)

Time:11-14

This is a tricky question to search. I'm drawing a line in HLSL, and I want to define the opacity of the line based on the horizonal coordinate of each pixel.

Picture a vertical line, with 10 pixel width. The left and right most pixels should be nearly fully transparent, the center pixels fully opaque, and a falloff somewhere in between. In my shader, I will have the "horizontal coordinates" as a factor 0->1, where 0 is left-most and 1 is right-most, and I'll have a single "feather" factor, also 0->1, which should make the line softer on the edges when it is 1.0, or very sharp at 0.0.

I realize that a fully robust system might need more information, such as where to begin and end the falloff. But assume that I just want to draw standard lines that look good at varying widths, while supplying a single feather factor. The feather should increase the falloff range, where feather=0.5 should start the left-side falloff at about 0.25, and feather=1.0 would have the falloff starting at the center of the line.

This is what I came up with, after playing around with desmos.com/calculator for a while. x is the horizontal factor:

float alpha = min( 1.0, x * 40.0 * (1.0-x) * (1.0 - (feather-0.1)) );

It works decently, but I'm not happy with the falloff behavior with the way I'm using the feather value. One needs to crank the feather all the way up to 0.95 to get the falloff to start where it should be at around 0.5.

Here is a preview of how this looks. The circle and blue line have a feather of 0.95, and the neon green diagonal line has a feather of 0.5, and you can see it is far too rough. All of these lines have a width of 10.

Drawn Lines

Any math people out there have any advice for a simple or better way to do this? Feel free to completely change the formula if you have a better way to pull it off. But if possible, please post the slope formula with standard ascii characters. I'm not the greatest with math symbols.

CodePudding user response:

There would be many ways to implement such function. A simple way can be:

Since the current alpha function you made is based on parabolla,

float alpha2 = 1.0f - pow((x - 0.5f) / 0.5f, 2.0f);

make a sharper fall-off function by using higher power.

float alpha32 = 1.0f - pow((x - 0.5f) / 0.5f, 32.0f);

And mix these two based on feather value.

float alpha = lerp(alpha32, alpha2, feather * feather);
  • Related