|
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.0 * 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.xx)); |
|
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.xx)); |
|
42 |
|
43 excluded = mix(temp, // left < bottom < right (see calculation of temp) |
|
44 excluded, step(bottomXTemp, left.xx)); |
|
45 |
|
46 excluded = mix(vec2(area, area), // right < bottom < top |
|
47 excluded, step(bottomXTemp, right.xx)); |
|
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().xxxx; |
|
57 } |
|
58 |