@@ -62,6 +62,29 @@ void main(void)
6262 gl_Position = vec4 (2.0 , 2.0 , 0.0 , 1.0 );
6363 return ;
6464 }
65+ float lineLength = length (vec2 (deltaCB.x, deltaCB.y / aspect)) / pixelWidth;
66+ // if lines reverse upon themselves and are not nearly the same length, skip
67+ // joins. This is a heuristic; the correct method would to be to pass some
68+ // sort of length of the adjacent line to the fragment renderer and adjust
69+ // which fragments are rendered, but this is much more complex.
70+ float abLimit = length (vec2 (A.x - B.x, (A.y - B.y) / aspect)) / pixelWidth;
71+ float dcLimit = length (vec2 (D.x - C.x, (D.y - C.y) / aspect)) / pixelWidth;
72+ if (abLimit >= lineLength - antialiasing - strokeWidth * 0.5 && abLimit <= lineLength + antialiasing + strokeWidth * 0.5 ) {
73+ abLimit = 0.0001 ;
74+ } else {
75+ if (abLimit < lineLength) abLimit = lineLength;
76+ abLimit = (strokeWidth - antialiasing) / (abLimit + antialiasing);
77+ if (abLimit < 0.0001 ) abLimit = 0.0001 ;
78+ if (abLimit > 0.1 ) abLimit = 0.1 ;
79+ }
80+ if (dcLimit >= lineLength - antialiasing - strokeWidth * 0.5 && dcLimit <= lineLength + antialiasing + strokeWidth * 0.5 ) {
81+ dcLimit = 0.0001 ;
82+ } else {
83+ if (dcLimit < lineLength) dcLimit = lineLength;
84+ dcLimit = (strokeWidth - antialiasing) / (dcLimit + antialiasing);
85+ if (dcLimit < 0.0001 ) dcLimit = 0.0001 ;
86+ if (dcLimit > 0.1 ) dcLimit = 0.1 ;
87+ }
6588 float angleCB = atan2(deltaCB.y, deltaCB.x * aspect);
6689 // values we need to pass along
6790 strokeColorVar = vec4 (strokeColor, strokeOpacity);
@@ -78,7 +101,7 @@ void main(void)
78101 // by default, offset by the width and don't extend lines. Later,
79102 // calculate line extensions based on end cap and end join modes
80103 float yOffset = strokeWidth + antialiasing;
81- if (vertex == 0 || vertex == 2 ) yOffset *= - 1.0 ;
104+ if (vertex == 0 ) yOffset *= - 1.0 ;
82105 yOffset += strokeWidth * offset;
83106 float xOffset = 0.0 ;
84107 // end caps
@@ -105,7 +128,7 @@ void main(void)
105128 angleABC = (mod (angleABC + 3.0 * PI, 2.0 * PI) - PI) / 2.0 ;
106129 cosABC = cos (angleABC); sinABC = sin (angleABC);
107130 // if this angle is close to flat, pass-through the join
108- if (nearMode >= 4 && cosABC > 0.999999 ) {
131+ if (nearMode >= 4 && ( cosABC > 0.999999 || cosABC < abLimit) ) {
109132 nearMode = 3 ;
110133 }
111134 // miter, miter-clip
@@ -138,7 +161,7 @@ void main(void)
138161 angleBCD = (mod (angleBCD + 3.0 * PI, 2.0 * PI) - PI) / 2.0 ;
139162 cosBCD = cos (angleBCD); sinBCD = sin (angleBCD);
140163 // if this angle is close to flat, pass-through the join
141- if (farMode >= 4 && cosBCD > 0.999999 ) {
164+ if (farMode >= 4 && ( cosBCD > 0.999999 || cosBCD < dcLimit) ) {
142165 farMode = 3 ;
143166 }
144167 // miter, miter-clip
@@ -159,8 +182,6 @@ void main(void)
159182 B.y + (xOffset * sin (angleCB) + yOffset * cos (angleCB)) * pixelWidth * aspect,
160183 B.z, 1.0 );
161184 // store other values needed to determine which pixels to plot.
162- float lineLength = length (vec2 (deltaCB.x, deltaCB.y / aspect)) / pixelWidth;
163-
164185 if (vertex == 0 || vertex == 1 ) {
165186 subpos = vec4 (xOffset, yOffset, lineLength - xOffset, strokeWidth);
166187 info = vec4 (float (nearMode), float (farMode), offset, 0.0 );
0 commit comments