Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a nicer approximation for anti-aliasing. #1822

Merged
merged 4 commits into from Oct 13, 2017
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Share the antialiasing code between shaders.

  • Loading branch information
nical committed Oct 13, 2017
commit 2cad56d146304017ce2c74367282c4a299aa81cc
@@ -155,7 +155,7 @@ void main(void) {
clip_relative_pos);

// Get AA widths based on zoom / scale etc.
float aa_range = 0.4 * length(fwidth(local_pos));
float aa_range = compute_aa_range(local_pos);

// SDF subtract edges for dash clip
float dash_distance = max(d0, -d1);
@@ -167,7 +167,7 @@ void main(void) {
float d = mix(dash_distance, dot_distance, vAlphaMask.x);

// Apply AA.
d = 1.0 - smoothstep(-aa_range, aa_range, d);
d = distance_aa(aa_range, d);

// Completely mask out clip if zero'ing out the rect.
d = d * vAlphaMask.y;
@@ -138,9 +138,9 @@ float rounded_rect(vec2 pos) {

// Apply AA
// See comment in ps_border_corner about the choice of constants.
float aa_range = 0.4 * length(fwidth(pos));
float aa_range = compute_aa_range(pos);

return 1.0 - smoothstep(-aa_range, aa_range, current_distance);
return distance_aa(aa_range, current_distance);
}

void main(void) {
@@ -719,6 +719,32 @@ void write_clip(vec2 global_pos, ClipArea area) {

#ifdef WR_FRAGMENT_SHADER

/// Find the appropriate half range to apply the AA smoothstep over.
/// This range represents a coefficient to go from one CSS pixel to half a device pixel.
float compute_aa_range(vec2 position) {
// We use 0.4 instead of 0.5 here to compensate for the fact that length(fw) is equal
// to sqrt(2) times the device pixel ratio in the typical case.
// This coefficient is chosen to ensure that a sample that any sample 0.5 pixels
// or more inside of the shape has no anti-aliasing applied to it (since pixels are
// sampled at their center, such a pixel (axis aligned) is fully inside the border),
// so that antialiased curves properly connect with non-antialiased vertical or horizontal
// lines.
//
// Using larger aa steps is quite common when rendering shapes with distance fields.
// It gives a smoother (although blurrier look) by extending the range that is smoothed
// to produce the anti aliasing. In our case, however, extending the range inside of
// the shape causes noticeable artifacts at the junction between an antialiased corner
// and a straight edge.
return 0.4 * length(fwidth(position));
}

/// Return the blending coefficient to for distance antialiasing.
///
/// 0.0 means inside the shape, 1.0 means outside.
float distance_aa(float aa_range, float signed_distance) {
return 1.0 - smoothstep(-aa_range, aa_range, signed_distance);
}

#ifdef WR_FEATURE_TRANSFORM
float signed_distance_rect(vec2 pos, vec2 p0, vec2 p1) {
vec2 d = max(p0 - pos, pos - p1);
@@ -733,10 +759,10 @@ vec2 init_transform_fs(vec3 local_pos, out float fragment_alpha) {
float d = signed_distance_rect(pos, vLocalBounds.xy, vLocalBounds.zw);

// Find the appropriate distance to apply the AA smoothstep over.
float aa_range = 0.4 * length(fwidth(pos.xy));
float aa_range = compute_aa_range(pos.xy);

// Only apply AA to fragments outside the signed distance field.
fragment_alpha = 1.0 - smoothstep(-aa_range, aa_range, d);
fragment_alpha = distance_aa(aa_range, d);

return pos;
}
@@ -324,19 +324,7 @@ void main(void) {

alpha = min(alpha, do_clip());

// Find the appropriate range to apply the AA smoothstep over.
// the aa step represents a coefficient to go from one CSS pixel to half a device pixel.
// We use 0.4 here to compensate for the fact that length(fw) is equal to sqrt(2) times
// the device pixel ratio in the typical case.
// Using larger aa steps is quite common when rendering shapes with distance fields.
// It gives a smoother (although a bit blurrier look) by extending the range that is
// smoothed to produce the anti aliasing. In our case, however, extending the range inside
// of the shape causes noticeable artifacts at the junction between an antialiased corner
// and a straight edge.
// The coefficient below is chosen to ensure that a sample that is 0.5 pixels or more inside of the
// curve shape has no anti-aliasing applied to it (since pixels are sampled at their center, such a
// pixel is fully inside the border.
float aa_range = 0.4 * length(fwidth(local_pos));
float aa_range = compute_aa_range(local_pos);

float distance_for_color;
float color_mix_factor;
@@ -373,10 +361,10 @@ void main(void) {
float d = mix(max(d_main, -d_inner), d_main, vSDFSelect);

// Only apply AA to fragments outside the signed distance field.
alpha = min(alpha, 1.0 - smoothstep(-aa_range, aa_range, d));
alpha = min(alpha, distance_aa(aa_range, d));

// Get the groove/ridge mix factor.
color_mix_factor = smoothstep(-aa_range, aa_range, -d2);
color_mix_factor = distance_aa(aa_range, d2);

This comment has been minimized.

@kvark

kvark Oct 12, 2017

Member

shouldn't this be 1.0 - distance_aa(aa_range, -d2) instead?

} else {
// Handle the case where the fragment is outside the clip
// region in a corner. This occurs when border width is
@@ -408,7 +396,7 @@ void main(void) {
// Select color based on side of line. Get distance from the
// reference line, and then apply AA along the edge.
float ld = distance_to_line(vColorEdgeLine.xy, vColorEdgeLine.zw, local_pos);
float m = smoothstep(-aa_range, aa_range, ld);
float m = distance_aa(aa_range, -ld);

This comment has been minimized.

@kvark

kvark Oct 12, 2017

Member

shouldn't this be 1.0 - distance_aa(aa_range, ld)?

This comment has been minimized.

@nical

nical Oct 12, 2017

Author Collaborator

At a certain point my brain decided that it was equivalent, but now I am very tired and counting on the test run (and/or a good night of sleep) to help coming up with a more definitive answer to this question.
(edit:) I reactivated my poor brain and I am pretty sure it's the same thing.

This comment has been minimized.

@kvark

kvark Oct 12, 2017

Member

Actually, I think you are correct here. Will see the try push and merge if it's ok.

vec4 color = mix(color0, color1, m);

oFragColor = color * vec4(1.0, 1.0, 1.0, alpha);
@@ -253,7 +253,7 @@ void main(void) {
alpha = min(alpha, do_clip());

// Find the appropriate distance to apply the step over.
float aa_range = 0.4 * length(fwidth(local_pos));
float aa_range = compute_aa_range(local_pos);

// Applies the math necessary to draw a style: double
// border. In the case of a solid border, the vertex
@@ -290,7 +290,7 @@ void main(void) {
// Get the dot alpha
vec2 dot_relative_pos = vec2(x, pos.x) - vClipParams.zw;
float dot_distance = length(dot_relative_pos) - vClipParams.z;
float dot_alpha = 1.0 - smoothstep(-aa_range, aa_range, dot_distance);
float dot_alpha = distance_aa(aa_range, dot_distance);

// Select between dot/dash alpha based on clip mode.
alpha = min(alpha, mix(dash_alpha, dot_alpha, vClipSelect));
@@ -190,7 +190,7 @@ void main(void) {
#endif

// Find the appropriate distance to apply the step over.
float aa_range = 0.4 * length(fwidth(local_pos));
float aa_range = compute_aa_range(local_pos);

// Select the x/y coord, depending on which axis this edge is.
vec2 pos = mix(local_pos.xy, local_pos.yx, vAxisSelect);
@@ -214,7 +214,7 @@ void main(void) {
// Get the dot alpha
vec2 dot_relative_pos = vec2(x, pos.y) - vParams.yz;
float dot_distance = length(dot_relative_pos) - vParams.y;
alpha = min(alpha, 1.0 - smoothstep(-aa_range, aa_range, dot_distance));
alpha = min(alpha, distance_aa(aa_range, dot_distance));
break;
}
case LINE_STYLE_WAVY: {
@@ -248,9 +248,7 @@ void main(void) {
float d = min(d1, d2);

// Apply AA based on the thickness of the wave.
alpha = 1.0 - smoothstep(vParams.x - aa_range,
vParams.x + aa_range,
d);
alpha = distance_aa(aa_range, d - vParams.x);
break;
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.