From 30920e41a51fe99e2a362deb1933c3755c7912eb Mon Sep 17 00:00:00 2001 From: David Manthey Date: Tue, 3 Sep 2019 16:10:07 -0400 Subject: [PATCH] Improve how points with small radii or stroke widths are rendered. Before, a point with a radius < 1.5 would look odd, and a point with a stroke width < 1.5 wouldn't be as antialiased as it should have been. --- CHANGELOG.md | 5 +++++ src/webgl/pointFeature.js | 10 ++++++---- src/webgl/pointFeaturePoly.frag | 18 ++++++++++-------- src/webgl/pointFeatureSprite.frag | 20 +++++++++++--------- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89fb579837..b570a29352 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## Unreleased + +### Improvements +- Points with small radii or thin strokes are rendered better (#1021) + ## Version 0.19.6 ### Features diff --git a/src/webgl/pointFeature.js b/src/webgl/pointFeature.js index 0933f6e167..9b751ae316 100644 --- a/src/webgl/pointFeature.js +++ b/src/webgl/pointFeature.js @@ -349,10 +349,12 @@ var webgl_pointFeature = function (arg) { } s_updateStyleFromArray(key, styleArray, false); }); - if (m_this.visible() && needsRefresh) { - m_this.draw(); - } else if (needsRender) { - m_this.renderer()._render(); + if (refresh) { + if (m_this.visible() && needsRefresh) { + m_this.draw(); + } else if (needsRender) { + m_this.renderer()._render(); + } } return m_this; }; diff --git a/src/webgl/pointFeaturePoly.frag b/src/webgl/pointFeaturePoly.frag index 09318a964c..35c06e7043 100644 --- a/src/webgl/pointFeaturePoly.frag +++ b/src/webgl/pointFeaturePoly.frag @@ -23,7 +23,7 @@ void main () { discard; // If there is no stroke, the fill region should transition to nothing if (strokeVar == 0.0) { - strokeColor = vec4 (fillColorVar.rgb, 0.0); + strokeColor = vec4(fillColorVar.rgb, 0.0); endStep = 1.0; } else { strokeColor = strokeColorVar; @@ -31,16 +31,18 @@ void main () { } // Likewise, if there is no fill, the stroke should transition to nothing if (fillVar == 0.0) - fillColor = vec4 (strokeColor.rgb, 0.0); + fillColor = vec4(strokeColor.rgb, 0.0); else fillColor = fillColorVar; - // Distance to antialias over - float antialiasDist = 3.0 / (2.0 * radiusVar); + // Distance to antialias over. First number is in pixels + float antialiasDist = 1.5 / (radiusVar + strokeWidthVar); if (rad < endStep) { - float step = smoothstep (endStep - antialiasDist, endStep, rad); - gl_FragColor = mix (fillColor, strokeColor, step); + float step = smoothstep(max(0.0, endStep - antialiasDist), endStep, rad); + vec4 color = mix(fillColor, strokeColor, step); + float step2 = smoothstep(max(0.0, 1.0 - antialiasDist), 1.0, rad); + gl_FragColor = mix(color, vec4(color.rgb, 0.0), step2); } else { - float step = smoothstep (1.0 - antialiasDist, 1.0, rad); - gl_FragColor = mix (strokeColor, vec4 (strokeColor.rgb, 0.0), step); + float step = smoothstep(max(0.0, 1.0 - antialiasDist), 1.0, rad); + gl_FragColor = mix(strokeColor, vec4(strokeColor.rgb, 0.0), step); } } diff --git a/src/webgl/pointFeatureSprite.frag b/src/webgl/pointFeatureSprite.frag index e31a6e9c5e..fcaf263797 100644 --- a/src/webgl/pointFeatureSprite.frag +++ b/src/webgl/pointFeatureSprite.frag @@ -18,12 +18,12 @@ void main () { // No stroke or fill implies nothing to draw if (fillVar == 0.0 && strokeVar == 0.0) discard; - float rad = 2.0 * length (gl_PointCoord - vec2(0.5)); // distinct for sprite + float rad = 2.0 * length(gl_PointCoord - vec2(0.5)); // distinct for sprite if (rad > 1.0) discard; // If there is no stroke, the fill region should transition to nothing if (strokeVar == 0.0) { - strokeColor = vec4 (fillColorVar.rgb, 0.0); + strokeColor = vec4(fillColorVar.rgb, 0.0); endStep = 1.0; } else { strokeColor = strokeColorVar; @@ -31,16 +31,18 @@ void main () { } // Likewise, if there is no fill, the stroke should transition to nothing if (fillVar == 0.0) - fillColor = vec4 (strokeColor.rgb, 0.0); + fillColor = vec4(strokeColor.rgb, 0.0); else fillColor = fillColorVar; - // Distance to antialias over - float antialiasDist = 3.0 / (2.0 * radiusVar); + // Distance to antialias over. First number is in pixels + float antialiasDist = 1.5 / (radiusVar + strokeWidthVar); if (rad < endStep) { - float step = smoothstep (endStep - antialiasDist, endStep, rad); - gl_FragColor = mix (fillColor, strokeColor, step); + float step = smoothstep(max(0.0, endStep - antialiasDist), endStep, rad); + vec4 color = mix(fillColor, strokeColor, step); + float step2 = smoothstep(max(0.0, 1.0 - antialiasDist), 1.0, rad); + gl_FragColor = mix(color, vec4(color.rgb, 0.0), step2); } else { - float step = smoothstep (1.0 - antialiasDist, 1.0, rad); - gl_FragColor = mix (strokeColor, vec4 (strokeColor.rgb, 0.0), step); + float step = smoothstep(max(0.0, 1.0 - antialiasDist), 1.0, rad); + gl_FragColor = mix(strokeColor, vec4(strokeColor.rgb, 0.0), step); } }