Manually antialiased primitives using texturing

Sage
Posts: 1,232
Joined: 2002.10
Post: #1
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.
Quote this message in a reply
Member
Posts: 469
Joined: 2002.10
Post: #2
radeon 9800 fsaa is what you want Smile

---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #3
Re-read my post. FSAA looks like crap.
Quote this message in a reply
Member
Posts: 177
Joined: 2002.08
Post: #4
Perhaps you could store polygons in the stencil buffer and then run a blurring pixel shader that only affects the boundaries?
Quote this message in a reply
Member
Posts: 469
Joined: 2002.10
Post: #5
Quote:Originally posted by arekkusu
Re-read my post. FSAA looks like crap.
9800 not 9600 Rasp

They made orders of magnitude improvement between the two chipsets. 9800 FSAA actually runs at fullspeed and doesn't look like crap as it actually outlines the polygons via depth buffer comparison.

---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #6
Quote:Originally posted by kelvin
9800 FSAA actually runs at fullspeed and doesn't look like crap as it actually outlines the polygons via depth buffer comparison.


After spending a day testing 12 different video cards, I can tell you that you're wrong on both counts. The FSAA on the 9800 pro looks identical to the 9600 (x2 = 1 shade, x4 = 3 shades, x6 = 5 shades...)

It still eats fillrate too. Here's some meaningless numbers applicable only to my limited test app (thousands of points/lines/triangles drawn per second):

Code:
ALIASED         HARDWARE AA     FSAA X2         FSAA X4         FSAA X6         SOFTWARE AA
Radeon9800Pro    420/540/75    420/539/75    420/298/60    420/150/38    420/121/33    55/11/0

You can see the steady drop in line/triangle throughput as the FSAA buffers increase.

That said, the 9800 Pro was the fastest card of the 12...

Check some comparison pictures. (warning, graphics-heavy)
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #7
1) how much easier is FSAA to implement than other methods?
2) can I get that program you used? it looks nifty.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #8
Activating FSAA is as easy as adding two lines to your pixel format creation, and enabling MULTISAMPLE.

Activating regular hardware AA is as easy as enabling SMOOTH for each primitive (3 lines of code.)

Now, getting it to look correct, on all hardware is very hard. I've got points 99% right. Still working on lines and triangles.

I'll post a third page ("so, what other options are there") when I get things working well, along with the program source.



Of course... the real advantage of FSAA is that the alpha blended edges work with any geometry without sorting (i.e. the multisampling happens at the scene level, instead of at the primitive level... hence, full-scene AA) which makes it a win for 3D. For apps where sorting is not an issue (2D: pdf, flash, paint apps...) there's no advantage whatsoever.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #9
arekkusu Wrote:Now, getting it to look correct, on all hardware is very hard.

Update, points and lines 100% working (but not line strips...)
Triangles still bogus.

More concise discussion, new pictures and benchmarks here.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #10
How close are you to a complete OpenGL implementation of Quartz? That would be very cool Smile
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #11
arekkusu Wrote:Update, points and lines 100% working (but not line strips...)
Triangles still bogus.

More concise discussion, new pictures and benchmarks here.
I am absolutely stunned at your research. Has Apple hired you to fix it all yet?
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #12
This is indeed something interesting to do. I have been thinking that creating solid polygons from lines, etc, and drawing them with multiple passes would be the easiest, it would at least get the shape of points and lines right, even if it's anti-aliasing is probably not quite up to quartz levels, unless lots of passes are used.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #13
OneSadCookie Wrote:How close are you to a complete OpenGL implementation of Quartz? That would be very cool Smile

That's not my intent, and beyond my ability (probably anyone's ability outside of Apple.) For starters Quartz allows a coord system much bigger than any GPU's max viewport size, so you'd have to tile chunks in multiple passes when i.e. printing. Or even stretching a window across two Cinema displays.

And speaking of printing of course you have to have portability across devices, which GL can't do. I know there are already GL->Postscript converters, so it's possible in theory... but I don't want to even think about it.

The biggest block is that Quartz has to be bit for bit identical across machines. My texturing approach isn't, because in GL texturing (like everything else) is subject to the implementation details of the GPU so there are tiny differences.

BUT, I'm sure there are plenty of developers who could live with that if it meant a 1000x speedup Smile Just make it an optional Quartz rendering mode...

All I really want is hardware accelerated NSBezierPath. See? That's not too much to ask for, is it?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #14
skyhawk Wrote:I am absolutely stunned at your research. Has Apple hired you to fix it all yet?

Hrmmm. Not yet. But, errr, hmmmm. No comment.


DoG Wrote:I have been thinking that creating solid polygons from lines, etc, and drawing them with multiple passes would be the easiest.

That's the accumulation buffer method, and it's been around forever. It works fine, but it takes a lot of passes and is very slow, especially given that consumer GPUs don't have hardware acceleration for the accumulation buffer.

The texturing approach is quite fast. It is just tricky getting every little detail right.
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #15
You said you use mipmapping, but why? I dont see the point of doing that. I would assume you shrink the outline of all polygons by 1/2 px, then add a 1px border with a full color->transparent gradient. The most intensive part of this is getting the shrinking and border right, but it is quite simple, algorithmically.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  How to render points manually NCarter 9 5,814 Jan 13, 2003 05:22 PM
Last Post: henryj