Alias-free drawing of triangles, proof of concept

An image is a thousand words, here’s what I’ve rendered without using any hardware facilities like FSAA/MSAA:

I’ve uploaded the source-code + description at http://www.savefile.com/files/1342505

My questions are:

  1. do you know some similar concept, published anywhere?
  2. would drawing antialiased lines (2-3px in size) over the regularly-drawn polygons be a better solution? I’ve seen some horrible performance with drawing lines, but that could have been a driver-issue.
  3. could you help in the maths of extending the triangle in such a way, that each 2D rasterized edge is 1-2 pixels away.
  4. how do you think games like “RatchetAndClank:ToD” and Resistance2 draw everything alias-free?
    My target vcard is nVidia DX9c-class, (mine is GF7600).

P.S. don’t mind the strange uniDot0 uniforms, they’ll go away and be replaced with the vertex-attribute gl_Vertex.w (specifying index of current vertex: 0,1,2).

Btw, I know about GL_POLYGON_SMOOTH, it just doesn’t work on my PC, and from:
http://homepage.mac.com/arekkusu/bugs/invariance/HWAA.html
I can see that we can’t really rely on such HWAA, or its 3 bits of precision.

Just curious , what makes you think RatchetAndClank:ToD and Resistance2 don’t just use the standard hardware AA? Is there some screen shots or forum discussions we can look at?

As for this technique, option 2 with antialiased lines has been around for a long time. (have seen it on many old demos)

As for what could go wrong with this technique, I suspect the main problems will occur when you actually try to render a mesh with it as inner triangles will not be rendered correctly. The other problem is that you have to sort you scene geometry manually from front to back to make it work.

But I could be wrong, so try it with a real scene with a few meshes and find out.

ToD already is as jaggy-free as these images:
http://kotaku.com/photogallery/resistance2/1000577035?viewSize=thumb1280x1280

It was the first thing I noticed in the demo of ToD, viewing it in 720p via HDMI on a 1680x1050 screen. I moved the camera around to force some of the edges to have angles suitable for heavy aliasing, but even then it stayed perfect.

Yes, but that is not an argument against FSAA. Maybe they just enable FSAA by default and you can’t disable it (or does the game expose such an option?). I don’t think there is any other way, that would result in playable framerates.

Jan.

Uhm, the games are for Playstation3 and at least R&C does not drop frames ever, we’ll have to wait till Sept to see Resistance2.

Meanwhile, I made the antialiasing just use lines, drawing in wireframe mode and 3px line-size. Got it to work a bit, just have to change some maths, for the clipspace is giving me trouble.

BTW, I would trust a web posted screen shot anyway, as per even if those are using in-game geometry and textures, usually shots are rendered non-real-time with all the AA you could possibly want…

Since ToD is 720P max, seems like they would have enough processing power left to do hardware AA.

If I had the problem of aliasing I would skip hardware AA and do an image space post process. You would need to have per-pixel normals (G-Buffer), readable Z, and direction of motion for this to work. Also this method basically integrates with standard Z aware image space motion blur techniques. Basic concept is when under motion you blur in the direction of motion, lowering contribution of samples which Z is out of range and should be included less in the blur. No AA is needed under motion blur. For pixels moving too little to be included in motion blur you project the normal into screen space (XYZ->XY) and get a vector perpendicular to the projected normal, this vector is the edge direction. Now blur in the direction of the edge instead of the direction of motion and adjust the weight of the samples used in the blur based on Z differences or if you compute the edge direction as a full screen image pass, you could also use the difference of edge direction in the weights for the samples used in the blur.

FYI, according to Insomniac’s R&D website, Resistance Fall of Man used a 1280x720 32bit RGBA 2xMSAA render buffer and a 32-bit depth buffer. For NTSC/PAL, 1280x720 is just down-sampled (even better AA).

Yes, I’ve read that document, and knew that months before it - regular jaggies are visible in Resistance1. It’s RCF:ToD and Resistance2 that employ a different approach.

I’ve managed to make the line-based edge-smoothing, continuing from the code I had attached. (1st pass-render opaque geometry as usual, 2nd pass- enable a flag in the shaders, and draw all in wireframe with 3px line-size). Could draw a thousand such triangles with same coords (and thus same values for the uniDot0/1/2) but different matrices. Yet, when I integrated the shaders into a whole mesh viewer, where on every polygon I have to change the uniforms, OpenGL would refuse to set the uniforms ^^". Might have to do with the fact that I’m using immediate-mode calls…
I’ll try later with using vertex-attribs instead of uniforms (as this is how the final version will have to be anyway).

It’s RCF:ToD and Resistance2 that employ a different approach.

You didn’t notice how much that Resistance 2 image is blurred? It’s easy to hide aliasing artifacts by doing a low-pass filter over everything. There may not be any aliasing artifacts visible, but there is just as little sharpness.

In Resistance 2’s case, they’re doing depth-of-field. So the blurry sections are farther away.

In the image that I posted a link to, the soldier to the right is in focus of the DOF, and yet the edges are movie-quality, imho.
Also, if you look at the gradient at 1037:116, you’ll notice you need at least a 127x127 filter kernel to get such smoothness, yet the image is not that blurry… so any post-processing filtering is out of the question. And you’d need 64x64 FSAA/MSAA for those gradients. Only those 3px lines seem to be a viable answer :slight_smile:

the soldier to the right is in focus of the DOF, and yet the edges are movie-quality, imho.

I would also like to point out that it is a screenshot, and thus subject to fakery. Not to mention the fact that there is aliasing to be seen on that soldier.

Also, if you look at the gradient at 1037:116, you’ll notice you need at least a 127x127 filter kernel to get such smoothness, yet the image is not that blurry… so any post-processing filtering is out of the question.

Except that the image is clearly blurry. Look at the background and notice the lack of sharpness.

Only those 3px lines seem to be a viable answer

Except that that’s not an answer either, because that’s merely blurring the edge of a triangle. Blur is not anti-aliasing; it’s simply noise.

Just took a look at Ratchet ToD (my brother had borrowed the PS3 so I couldn’t comment before), and at 480P I still see some down-sampled aliasing. Probably safe to assume that ToD is simply doing hardware 2-MSAA, especially at 60fps.

BTW, drawing lines probably isn’t a good idea performance wise (at least on the newer NVidia cards) because fragment shaders tend to have to run on a screen space chunk of pixels at a time (32pix for GeForce 8 series, not sure if its 8x4 block or what) and in many cases a line doesn’t cover a good amount of pixels in the block and fragment shader computations go waisted. So you might want to just profile drawing the lines only to see how it effects performance.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.