Skip to content

Commit 29d290f

Browse files
committed
Explain pen line shader better
1 parent c1d4462 commit 29d290f

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

src/shaders/sprite.frag

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,21 @@ void main()
214214
// Maaaaagic antialiased-line-with-round-caps shader.
215215
// Adapted from Inigo Quilez' 2D distance function cheat sheet
216216
// https://www.iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
217+
218+
// The xy component of u_penPoints is the first point; the zw is the second point.
219+
// This is done to minimize the number of gl.uniform calls, which can add up.
217220
vec2 pa = v_texCoord - u_penPoints.xy, ba = u_penPoints.zw - u_penPoints.xy;
218-
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
221+
// Magnitude of vector projection of this fragment onto the line (both relative to the line's start point).
222+
// This results in a "linear gradient" which goes from 0.0 at the start point to 1.0 at the end point.
223+
float projMagnitude = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
224+
225+
float lineDistance = length(pa - (ba * projMagnitude));
219226

220-
float cappedLine = clamp((u_lineThickness + 1.0) * 0.5 - length(pa - ba*h), 0.0, 1.0);
227+
// The distance to the line allows us to create lines of any thickness.
228+
// Instead of checking whether this fragment's distance < the line thickness,
229+
// utilize the distance field to get some antialiasing. Fragments far away from the line are 0,
230+
// fragments close to the line are 1, and fragments that are within a 1-pixel border of the line are in between.
231+
float cappedLine = clamp((u_lineThickness + 1.0) * 0.5 - lineDistance, 0.0, 1.0);
221232

222233
gl_FragColor = u_lineColor * cappedLine;
223234
#endif // DRAW_MODE_line

0 commit comments

Comments
 (0)