arekkusu
2003.11.03, 06:08 PM
I'm looking for info. The question is below, but first comes the background.
My problem:
New hardware (ATI Radeon 9600 family) dropped support for hardware AA polygons. AA points and lines aren't exposed by the current drivers either, so if you want any type of hardware AA, you have to use FSAA which eats VRAM/fillrate and looks bad.
By "looks bad", I mean in maximum quality mode (6 sample buffers) you get 6 intermediate AA shades, whereas hardware AA on a Radeon 7500 gives you 8. 2 or 4 sample buffers look even worse.
My goal:
Replace GL_POINTS, GL_LINES, GL_TRIANGLES, GL_QUADS and derivatives with nicely antialiased primitives, using texture filtering hardware, which is about the only thing still reliable across currently sold video cards. AA quality is higher priority than speed, although speed is also important. Primitives in 2D space are much higher priority than in 3D space. Essentially, I want an OpenGL implementation of CoreGraphics primitives.
Examples:
Points can be replaced by one alpha textured quad, with an appropriately AA'd circle graphic. Texture filtering keeps the AA sharp, and a texture size of around 64x64 is enough for my needs (512x512 would be needed for maximum fidelity, but I think bilinear filtering provides a close enough approximation when the enlargement is limited to <= 4x, and blended 512 px points start to eat fillrate pretty fast. Not to mention native GL points can't get bigger than 10 px on some hardware.) The AA graphic can also have custom falloff to vary between hard a hard edged circle and a linear sphere. The point alpha texture is modulated with the current color or, with multitexturing, other textures.
Line segments similarly can be replaced by one alpha textured quad, but now some additional math is required. You have to project the quad corners out from the line endpoints, which involves finding the perpendicular vector and normalizing. Once this is done, an e.g. 1x64 px texture can be stretched along the length of the line to smooth edges. You get 256 shades, so it comes out looking better than any native hardware implementation. Endpoints aren't smoothed, so they need extra attention if you use thick lines (again, native GL limitation of 1 or 10 px wide lines goes away.)
My problem:
Polygons. I have not yet found a way to exactly duplicate the hardware AA, because it would involve subtracting alpha from some of the filled polygon, which might be doable with some destination alpha tricks but would really suck. What I do have is stroking the polygon edge with the textured line from the above example. This makes the polygon at least 1 px thicker than the aliased version, but I can probably live with that (the seams in natively AA'd tristrips wouldn't occur, at least...) There is also the problem of what to do at polygon vertices. If I stroke the line with a tristrip all around the boundary, GL will fill the vertex corners with one extra triangle, which looks pretty bad if you stroke with wide lines (hard corner, linear blending artifacts.) A better solution would be to fill the corners with the point texture to get rounded edges, but I am still working this out.
There is also a fairly large jump in the number of CPU-side calculations needed to get three normals per triangle, plus vertex normals if rounded corners are desired. And collinear edge cases have to be handled, so there are some extra compares around the actual drawing. And while interpolated color across the polygon looks all right with a wide stroke, I am not sure what to do with an existing texture. Repeat? Extend the border? Hrmmm.
So,
My question:
Can somebody point me towards existing implementations of manually antialiased GL primitives? I'm not interested in a full software rasterizer. I want to leverage the existing texturing hardware.
if you have ideas re: the polygon problems, I'm all ears. I'm also open to ATI vertex shader ideas, since the only hardware where I have to go through all this is guaranteed to have shader support. I don't know anything about writing shaders yet-- I imagine the normal vector part would be easy, but I think you can not generate any new vertices? E.g. two line endpoints -> four AA quad points, three polygon points -> up to 12 AA polygon points.
My problem:
New hardware (ATI Radeon 9600 family) dropped support for hardware AA polygons. AA points and lines aren't exposed by the current drivers either, so if you want any type of hardware AA, you have to use FSAA which eats VRAM/fillrate and looks bad.
By "looks bad", I mean in maximum quality mode (6 sample buffers) you get 6 intermediate AA shades, whereas hardware AA on a Radeon 7500 gives you 8. 2 or 4 sample buffers look even worse.
My goal:
Replace GL_POINTS, GL_LINES, GL_TRIANGLES, GL_QUADS and derivatives with nicely antialiased primitives, using texture filtering hardware, which is about the only thing still reliable across currently sold video cards. AA quality is higher priority than speed, although speed is also important. Primitives in 2D space are much higher priority than in 3D space. Essentially, I want an OpenGL implementation of CoreGraphics primitives.
Examples:
Points can be replaced by one alpha textured quad, with an appropriately AA'd circle graphic. Texture filtering keeps the AA sharp, and a texture size of around 64x64 is enough for my needs (512x512 would be needed for maximum fidelity, but I think bilinear filtering provides a close enough approximation when the enlargement is limited to <= 4x, and blended 512 px points start to eat fillrate pretty fast. Not to mention native GL points can't get bigger than 10 px on some hardware.) The AA graphic can also have custom falloff to vary between hard a hard edged circle and a linear sphere. The point alpha texture is modulated with the current color or, with multitexturing, other textures.
Line segments similarly can be replaced by one alpha textured quad, but now some additional math is required. You have to project the quad corners out from the line endpoints, which involves finding the perpendicular vector and normalizing. Once this is done, an e.g. 1x64 px texture can be stretched along the length of the line to smooth edges. You get 256 shades, so it comes out looking better than any native hardware implementation. Endpoints aren't smoothed, so they need extra attention if you use thick lines (again, native GL limitation of 1 or 10 px wide lines goes away.)
My problem:
Polygons. I have not yet found a way to exactly duplicate the hardware AA, because it would involve subtracting alpha from some of the filled polygon, which might be doable with some destination alpha tricks but would really suck. What I do have is stroking the polygon edge with the textured line from the above example. This makes the polygon at least 1 px thicker than the aliased version, but I can probably live with that (the seams in natively AA'd tristrips wouldn't occur, at least...) There is also the problem of what to do at polygon vertices. If I stroke the line with a tristrip all around the boundary, GL will fill the vertex corners with one extra triangle, which looks pretty bad if you stroke with wide lines (hard corner, linear blending artifacts.) A better solution would be to fill the corners with the point texture to get rounded edges, but I am still working this out.
There is also a fairly large jump in the number of CPU-side calculations needed to get three normals per triangle, plus vertex normals if rounded corners are desired. And collinear edge cases have to be handled, so there are some extra compares around the actual drawing. And while interpolated color across the polygon looks all right with a wide stroke, I am not sure what to do with an existing texture. Repeat? Extend the border? Hrmmm.
So,
My question:
Can somebody point me towards existing implementations of manually antialiased GL primitives? I'm not interested in a full software rasterizer. I want to leverage the existing texturing hardware.
if you have ideas re: the polygon problems, I'm all ears. I'm also open to ATI vertex shader ideas, since the only hardware where I have to go through all this is guaranteed to have shader support. I don't know anything about writing shaders yet-- I imagine the normal vector part would be easy, but I think you can not generate any new vertices? E.g. two line endpoints -> four AA quad points, three polygon points -> up to 12 AA polygon points.