Introduction | Hardware AA | FSAA | Texture AA |
I came up with a set of tests which cover most of the 2D drawing needs I have. They are by no means a complete set of tests, merely the ones I thought of. Notably, line strip joining is absent.
Below is a screenshot of my test application. The test pattern mode displays sets of points, lines, and triangles in ways intended to test antialiasing quality in specific situations. At the bottom left a zoom-in of the currently selected region is shown so the pixels can be easily inspected. The current renderer name is written at the bottom; the first popup allows changing the rendering context between software, hardware AA, FSAA, etc. There is also an interactive mode, a performance mode, and some controls to manipulate the Texture AA parameters.
For illustration purposes, I've labeled each test in the screenshot, from A-N:
A | White points of integral sizes from 1 to 20 px. |
B | White 1 px points placed at fractional positions. |
C | White points of fractional sizes from 0 to 2 px. |
D | Lines of integral width from 1 to 20 px, of varying angle, with color gradient. |
E | Horizontal lines 1 px wide, with fractional length from 0 to 3 px, with red-blue gradient. |
F | Same as E except vertical. |
G | 1 px wide horizontal lines placed at fractional vertical positions, with red-white gradient. |
H | Horizontal lines placed at integral positions, with fractional width from 2 to 0 px, with green-white gradient. |
I | Same as H, except blue-white gradient, and line stipple pattern applied. |
J | White horizontal lines of integral width from 1 to 10 px, aligned to integral positions. |
K | White horizontal lines 1 px wide and 1 px long, placed at fractional horizontal positions. |
L | White horizontal lines 1 px long, with fractional width from 0 to 2 px. |
M | Triangles of varying acuteness, with color gradient. |
N | Radial pattern of white 1 px lines drawn in background at 20% opacity. The right half has a stipple pattern of increasing integral length applied, starting at 1 px pointing down. |
The screenshot shows the test pattern as rendered by Quartz. This is the "best" quality; all primitives are rendered with 8 subpixel bits of precision and, while there is some room for fudging (depending on for example the line cap mode) all tests are passed to my satisfaction. If OpenGL looked like this, I wouldn't have to do anything extra.
Unfortunately, OpenGL is a long ways away from looking this good.
Here is the same test pattern on various OpenGL renderers under Mac OS X 10.3.2, with regular antialiasing (GL_POINT_SMOOTH, GL_LINE_SMOOTH, GL_POLYGON_SMOOTH turned on, with all hints set to GL_NICEST.)
Software rendererPoints looks fine, except that in test C they don't fade out quickly enough as the size goes to zero. Lines have several issues. First, the maximum line width is 10 px, fine per spec but not enough for my apps. Also, the lines are drawn as a sequence of either horizontal or vertical strips depending if the angle is less or greater than 45 degrees. This is correct according to the spec for aliased lines, but is wrong for antialiased lines, and causes several problems: in D and N, the end caps ignore the line angle, the width ignores the line angle (at 45 degrees, it is too skinny by a factor of sqrt(2)), and the stipple pattern is distorted with the angle. Next, there are two problems with line length: there is no subpixel precision, so E, F and K fail, and the length is always one pixel too long as seen in the overlap between G, H and I. It is not pictured here, but this overlap is a huge problem when drawing bezier curves. Lastly there are some diagonal artifacts in N. Triangles look OK, but there are only three subpixel bits of precision so some banding is visible. |
Rage 128Points are not antialiased and appear as squares. There is no fractional size or positioning. Lines are only antialiased at a width of 1 px. The max width is reported to be 10 px, but does go wider. They have the same "wrong spec" problems as in the Software renderer. The length is correct, but there is no fractional length, width or positioning. The stipple pattern shows faint lines where there ought to be none. Triangles are not antialiased, and the alignment is a little skewed. |
Rage 128 ProIdentical to Rage 128, except that the faint lines in the stipple pattern are fixed. |
Radeon 7000Points are not antialiased, but show diagonal antialiasing seams. There is no fractional size or positioning. Lines are antialiased with three subpixel bits. They have the "wrong spec" end cap and stipple problems, but the width is correctly adjusted with the angle. The max width is reported to be 10 px, but does go wider. Fractional length and positioning work, but widths less than 1.0 px do not. Triangles look OK, but there are only three subpixel bits of precision so some banding is visible. |
Radeon 7500Identical to Radeon 7000, except for slightly different blending near the center of test N. |
Radeon 8500, 9000 and 9200Identical to Radeon 7500, except for slightly different rounding in test B. Also, the stipple pattern in the zoom region box wraps correctly. |
Radeon 9600, 9700 and 9800Points are not antialiased and appear as squares. There is no fractional size or positioning. Points smaller than 1.0 px are not drawn at all. Lines are not antialiased. They have the "wrong spec" end cap and width problems, and line stipple is ignored completely. Lines thinner than 1.0 px are not drawn at all. The max width is reported to be 10 px, but does go wider. There is no fractional length, width or positioning. Triangles are not antialiased. |
GeForce2 MXPoints are antialiased, but distorted at even sizes. There is no fractional size or positioning. Lines are sort of antialiased unless line stipple is on. The max width is reported to be 10 px, but actually only draws 1 px wide. There is no fractional length, width or positioning. The stipple pattern is distorted with the angle. Triangles are not antialiased. Slight skewing is visible. |
GeForce4 MXPoints are antialiased, but distorted at even sizes. There is no fractional size or positioning. Lines are sort of antialiased. The max width is reported to be 10 px, but actually only draws 1 px wide. Fractional length and positioning work, but fractional width only works if line stipple is on. With line stipple off, lines thinner than 1.0 px are smudged. The stipple pattern is distorted with the angle. Triangles look OK, but there are only three subpixel bits of precision so some banding is visible. |
GeForce4 TiPoints are antialiased, but distorted at even sizes. Fractional size or positioning tends to make the point not be drawn at all. Lines are antialiased and drawn according to the antialiased spec, so the end caps adjust to the angle correctly. The width also adjusts but overcompensates so angled lines are a little wider than they should be. The stipple pattern is still distorted with the angle. Fractional length, width, and positioning all work. Triangles are antialiased with only 1 subpixel bit, so there is very noticeable banding. |
GeForceFX 5200Identical to GeForce4 Ti, except that there is no fractional point size or positioning, and line width and stipple pattern correctly adjust with the angle. |
It should be obvious now that you can not depend on regular OpenGL antialiasing; each card behaves differently with many separate problems, and none of them are as good as Quartz. I'm not going to "rate" every GPU; you can do that for yourself just by looking at the screenshots. But if I was to pick out the best and worst quality, it seems to me that the GeForceFX is the best (although still a long way from Quartz) and the Radeon 9600/9700/9800 (the GPUs shipping in Apple's current top-of-the-line PowerBooks and G5s) are the worst. (NOTE: the ATI drivers in 10.3.3 significantly improve this, though.)
Another option is FSAA. Certainly anything would be better than the default Radeon 9600/9800 appearance, but FSAA turns out to be even worse overall...