Tweak pen shader to avoid float precision issues

This commit is contained in:
adroitwhiz
2020-04-25 19:43:20 -04:00
parent 4b2e17186b
commit 0b47d87f2f
2 changed files with 11 additions and 3 deletions

View File

@@ -214,7 +214,7 @@ void main()
// Un-premultiply alpha.
gl_FragColor.rgb /= gl_FragColor.a + epsilon;
#endif
#else // DRAW_MODE_line
// Maaaaagic antialiased-line-with-round-caps shader.
// Adapted from Inigo Quilez' 2D distance function cheat sheet
@@ -223,9 +223,14 @@ void main()
// The xy component of u_penPoints is the first point; the zw is the second point.
// This is done to minimize the number of gl.uniform calls, which can add up.
vec2 pa = v_texCoord - u_penPoints.xy, ba = u_penPoints.zw - u_penPoints.xy;
// Avoid division by zero
float baDot = dot(ba, ba);
baDot = (abs(baDot) < epsilon) ? epsilon : baDot;
// Magnitude of vector projection of this fragment onto the line (both relative to the line's start point).
// This results in a "linear gradient" which goes from 0.0 at the start point to 1.0 at the end point.
float projMagnitude = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
float projMagnitude = clamp(dot(pa, ba) / baDot, 0.0, 1.0);
float lineDistance = length(pa - (ba * projMagnitude));

View File

@@ -40,7 +40,10 @@ void main() {
position -= expandedRadius;
// Rotate quad to line angle
vec2 normalized = (u_penPoints.zw - u_penPoints.xy + epsilon) / (lineLength + epsilon);
vec2 pointDiff = u_penPoints.zw - u_penPoints.xy;
// Ensure line has a nonzero length so it's rendered properly
pointDiff.x = abs(pointDiff.x) < epsilon ? epsilon : pointDiff.x;
vec2 normalized = pointDiff / max(lineLength, epsilon);
position = mat2(normalized.x, normalized.y, -normalized.y, normalized.x) * position;
// Translate quad
position += u_penPoints.xy;