1 | float quad_aa()
|
---|
2 | {
|
---|
3 | float top = min(gl_FragCoord.y + 0.5, gl_TexCoord[0].x);
|
---|
4 | float bottom = max(gl_FragCoord.y - 0.5, gl_TexCoord[0].y);
|
---|
5 |
|
---|
6 | float area = top - bottom;
|
---|
7 |
|
---|
8 | float left = gl_FragCoord.x - 0.5;
|
---|
9 | float right = gl_FragCoord.x + 0.5;
|
---|
10 |
|
---|
11 | // use line equations to compute intersections of left/right edges with top/bottom of truncated pixel
|
---|
12 | vec4 vecX = gl_TexCoord[1].xxzz * vec2(top, bottom).xyxy + gl_TexCoord[1].yyww;
|
---|
13 |
|
---|
14 | vec2 invA = gl_TexCoord[0].zw;
|
---|
15 |
|
---|
16 | // transform right line to left to be able to use same calculations for both
|
---|
17 | vecX.zw = 2 * gl_FragCoord.x - vecX.zw;
|
---|
18 |
|
---|
19 | vec2 topX = vec2(vecX.x, vecX.z);
|
---|
20 | vec2 bottomX = vec2(vecX.y, vecX.w);
|
---|
21 |
|
---|
22 | // transform lines such that top intersection is to the right of bottom intersection
|
---|
23 | vec2 topXTemp = max(topX, bottomX);
|
---|
24 | vec2 bottomXTemp = min(topX, bottomX);
|
---|
25 |
|
---|
26 | // make sure line slope reflects mirrored lines
|
---|
27 | invA = mix(invA, -invA, step(topX, bottomX));
|
---|
28 |
|
---|
29 | vec2 vecLeftRight = vec2(left, right);
|
---|
30 |
|
---|
31 | // compute the intersections of the lines with the left and right edges of the pixel
|
---|
32 | vec4 intersectY = bottom + (vecLeftRight.xyxy - bottomXTemp.xxyy) * invA.xxyy;
|
---|
33 |
|
---|
34 | vec2 temp = mix(area - 0.5 * (right - bottomXTemp) * (intersectY.yw - bottom), // left < bottom < right < top
|
---|
35 | (0.5 * (topXTemp + bottomXTemp) - left) * area, // left < bottom < top < right
|
---|
36 | step(topXTemp, right));
|
---|
37 |
|
---|
38 | vec2 excluded = 0.5 * (top - intersectY.xz) * (topXTemp - left); // bottom < left < top < right
|
---|
39 |
|
---|
40 | excluded = mix((top - 0.5 * (intersectY.yw + intersectY.xz)) * (right - left), // bottom < left < right < top
|
---|
41 | excluded, step(topXTemp, right));
|
---|
42 |
|
---|
43 | excluded = mix(temp, // left < bottom < right (see calculation of temp)
|
---|
44 | excluded, step(bottomXTemp, left));
|
---|
45 |
|
---|
46 | excluded = mix(vec2(area, area), // right < bottom < top
|
---|
47 | excluded, step(bottomXTemp, right));
|
---|
48 |
|
---|
49 | excluded *= step(left, topXTemp);
|
---|
50 |
|
---|
51 | return (area - excluded.x - excluded.y) * step(bottom, top);
|
---|
52 | }
|
---|
53 |
|
---|
54 | void main()
|
---|
55 | {
|
---|
56 | gl_FragColor = quad_aa();
|
---|
57 | }
|
---|
58 |
|
---|