Skip to content

Commit ffddd7f

Browse files
authored
Merge pull request #667 from adroitwhiz/fix-safari-pen-again
Move pen point difference calculation from shader code to JS
2 parents bc5969f + 8b45114 commit ffddd7f

3 files changed

Lines changed: 12 additions & 7 deletions

File tree

src/PenSkin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ class PenSkin extends Skin {
323323
u_lineColor: __premultipliedColor,
324324
u_lineThickness: penAttributes.diameter || DefaultPenAttributes.diameter,
325325
u_lineLength: lineLength,
326-
u_penPoints: [x0, -y0, x1, -y1],
326+
u_penPoints: [x0, -y0, lineDiffX, -lineDiffY],
327327
u_stageSize: this.size
328328
};
329329

src/shaders/sprite.frag

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ uniform float u_ghost;
3737
uniform vec4 u_lineColor;
3838
uniform float u_lineThickness;
3939
uniform float u_lineLength;
40-
uniform vec4 u_penPoints;
4140
#endif // DRAW_MODE_line
4241

4342
uniform sampler2D u_skin;

src/shaders/sprite.vert

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ precision mediump float;
44
uniform vec2 u_stageSize;
55
uniform float u_lineThickness;
66
uniform float u_lineLength;
7+
// The X and Y components of u_penPoints hold the first pen point. The Z and W components hold the difference between
8+
// the second pen point and the first. This is done because calculating the difference in the shader leads to floating-
9+
// point error when both points have large-ish coordinates.
710
uniform vec4 u_penPoints;
811

912
// Add this to divisors to prevent division by 0, which results in NaNs propagating through calculations.
@@ -41,23 +44,26 @@ void main() {
4144
position.x *= u_lineLength + (2.0 * expandedRadius);
4245
position.y *= 2.0 * expandedRadius;
4346

44-
// Center around first pen point
47+
// 1. Center around first pen point
4548
position -= expandedRadius;
4649

47-
// Rotate quad to line angle
48-
vec2 pointDiff = u_penPoints.zw - u_penPoints.xy;
50+
// 2. Rotate quad to line angle
51+
vec2 pointDiff = u_penPoints.zw;
4952
// Ensure line has a nonzero length so it's rendered properly
5053
// As long as either component is nonzero, the line length will be nonzero
5154
// If the line is zero-length, give it a bit of horizontal length
5255
pointDiff.x = (abs(pointDiff.x) < epsilon && abs(pointDiff.y) < epsilon) ? epsilon : pointDiff.x;
5356
// The `normalized` vector holds rotational values equivalent to sine/cosine
5457
// We're applying the standard rotation matrix formula to the position to rotate the quad to the line angle
58+
// pointDiff can hold large values so we must divide by u_lineLength instead of calling GLSL's normalize function:
59+
// https://asawicki.info/news_1596_watch_out_for_reduced_precision_normalizelength_in_opengl_es
5560
vec2 normalized = pointDiff / max(u_lineLength, epsilon);
5661
position = mat2(normalized.x, normalized.y, -normalized.y, normalized.x) * position;
57-
// Translate quad
62+
63+
// 3. Translate quad
5864
position += u_penPoints.xy;
5965

60-
// Apply view transform
66+
// 4. Apply view transform
6167
position *= 2.0 / u_stageSize;
6268
gl_Position = vec4(position, 0, 1);
6369
#else

0 commit comments

Comments
 (0)