Last active
December 24, 2019 18:09
-
-
Save talyian/af79235492528123c1845cd1d45cc454 to your computer and use it in GitHub Desktop.
Slowest Font Renderer in the West
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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