Skip to content

Instantly share code, notes, and snippets.

@talyian
Last active December 24, 2019 18:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save talyian/af79235492528123c1845cd1d45cc454 to your computer and use it in GitHub Desktop.
Save talyian/af79235492528123c1845cd1d45cc454 to your computer and use it in GitHub Desktop.
Slowest Font Renderer in the West
uniform int n_lin_segments;
uniform vec2 lin_segments[256];
uniform int n_quad_segments;
uniform vec2 quad_segments[512];
varying vec3 pos;
varying vec2 uv;
void main() {
vec2 point = uv;
// point = (point + vec2(0.3, 0)) * 0.1;
int scan_count = 0;
gl_FragColor = vec4(uv, n_lin_segments, 1);
// find winding number for linear segments.
for(int i=0; i < n_lin_segments * 2; i+=2) {
vec2 pt0 = lin_segments[i];
vec2 pt1 = lin_segments[i+1];
float t = (point.y - pt0.y) / (pt1.y - pt0.y);
if (t >= 0 && t < 1) {
float x_intersect = t * (pt1.x - pt0.x) + pt0.x - point.x;
if (x_intersect <= 0) scan_count += 1;
}
}
// find winding number for quadratic segments
for(int i=0; i < n_quad_segments * 3; i += 3) {
vec2 pt0 = quad_segments[i];
vec2 pt1 = quad_segments[i+1];
vec2 pt2 = quad_segments[i+2];
// Get the quadratic terms by solving the
// parametric equation A*t*t + B*t + C = 0 for T in [0, 1) in x and y
vec2 p0 = pt0 - point, p1 = pt1 - point, p2 = pt2 - point;
vec2 A = p0 - 2 * p1 + p2,
B = -2*p0 + 2 * p1,
C = p0;
// find the values of T at point.y
float discriminant = B.y * B.y - 4 * A.y * C.y;
if (-0.0001 < A.y && A.y < 0.0001) {
// The Y-quadratic is degenerate, we have to solve linearly.
float t_1 = -C.y / B.y;
float x_1 = A.x * t_1 * t_1 + B.x * t_1 + C.x;
if (t_1 >= 0 && t_1 < 1 && x_1 < 0) { scan_count += 1; }
}
else if (discriminant <= 0) {
// curve does not touch the Y-line or is tangent
}
else {
// two T-intercept points that resultin Y = point.y
float sqrt_disc = sqrt(discriminant);
float t_1 = (-B.y - sqrt_disc) / (2.0 * A.y);
float x_1 = A.x * t_1 * t_1 + B.x * t_1 + C.x;
float t_2 = (-B.y + sqrt_disc) / (2.0 * A.y);
float x_2 = A.x * t_2 * t_2 + B.x * t_2 + C.x;
if (t_2 >= 0 && t_2 < 1 && x_2 < 0) { scan_count += 1; }
if (t_1 >= 0 && t_1 < 1 && x_1 < 0) { scan_count += 1; }
}
}
// shade the parts where we have an odd winding number
if (scan_count % 2 == 1) {
gl_FragColor = vec4(1, 0, 0, 1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment