"Pure and Correct AA"

Humus, between the anti-aliasing filter and the demosaicking with bayer pattern CCDs things don't quite work out like that. The PSF is more like a gaussian with a flattened top than a box AFAIR.

OK, poor example, but think of an old fashion analog camera instead.

It's possible that a pixel sized bounding box is the actual implementation, but that doesn't mean it's the best one.

Right. But if the pixel is square, the most correct representation is the integral of the function over the area of that square. I don't know what is the best shape of a pixel, maybe a hexagonal pattern would result in better quality?

As I already said, it is correct coverage, but it doesn't give you perfect antialiasing. In fact, a box filter is pretty poor at avoiding aliasing.

Yes, you're right. Let me say it like this instead: Correct coverage is the most correct representation for display using pixels. However, if you don't care about that, but only care about minimizing the amount of aliasing in the signal, then you should look at something like the sinc filter. However, the human eye does not see the real world anywhere close to a sinc filter, so this is hardly the ideal solution.

Because the framebuffer contains sRGB colors, not lRGB nor monitor color space. That's not an assumption, it's a definition (for Windows at least).

And linearly blending sRGB colors is wrong. But it has been done in the past because sRGB <-> lRGB conversion is expensive. IIRC R300 introduced sRGB downsampling and sRGB conversion after texture filtering. The latest DX10 hardware will finally do the conversion in all the proper places: before texture filtering, and for every read and write access to the framebuffer (alpha blending, AA resolve), if it is flagged as sRGB.

This is independent of the display hardware. Gamma correction in the pixel output pipeline is used (or rather: should be used, but most people never adjust it properly) to convert the sRGB colors from the framebuffer to the proper colors on screen. And that is the only place where you need to consider the monitor response curve.

OK, we may be closer in opinion than what your previous post seemed to imply. I'll still say though that the monitor response curve matters, because it's what's output on the screen in the end that dictates how well the antialiasing effect will be perceived. Assuming (or defining) it to 2.2 works fairly well in practice though. Still all math has to be done in linear "as output on the monitor" space. This is particularly important with HDR, where averaging linear light, or doing it "gamma correct" in linear scene light, results in horrible quality if the contrast is high. No built-in hardware resolve can solve that since we need to tonemap each individual sample first, then gamma-correct it, then average it. This will be one of the killer apps of individual MSAA sample access in DX10.
 
] No built-in hardware resolve can solve that since we need to tonemap each individual sample first, then gamma-correct it, then average it. This will be one of the killer apps of individual MSAA sample access in DX10.
Why would we want to average samples after gamma correction?
(btw, I found that swapping the order of tonemapping and averaging passes often produces extremely similar results, at least with a classic Reinhard's tone mapping operator..)
 
Yes, you're right. Let me say it like this instead: Correct coverage is the most correct representation for display using pixels. However, if you don't care about that, but only care about minimizing the amount of aliasing in the signal, then you should look at something like the sinc filter. However, the human eye does not see the real world anywhere close to a sinc filter, so this is hardly the ideal solution.
I guess you could call correct coverage the most correct representation, but I don't think it matters much. I certainly wouldn't call it the best representation in terms of perceived quality.

OK, we may be closer in opinion than what your previous post seemed to imply. I'll still say though that the monitor response curve matters, because it's what's output on the screen in the end that dictates how well the antialiasing effect will be perceived. Assuming (or defining) it to 2.2 works fairly well in practice though. Still all math has to be done in linear "as output on the monitor" space. This is particularly important with HDR, where averaging linear light, or doing it "gamma correct" in linear scene light, results in horrible quality if the contrast is high. No built-in hardware resolve can solve that since we need to tonemap each individual sample first, then gamma-correct it, then average it. This will be one of the killer apps of individual MSAA sample access in DX10.
I disagree with that operation order, but I think one source of disagreement is that we might interpret "linear color space" differently.

Linear color space models the physical properties of light. It's a theoretical model, independent of any display hardware. In lRGB space, the (channel) color value is proportional to the amount of photons/energy emitted in a certain part of the spectrum. RGB is, admittedly, a very coarse subdivision of the visible spectrum. E.g. a value of 1 is X photons per unit area, 255 means 255*X photons per unit area. Alpha can also be interpreted as area, btw.
This is the ideal space to do lighting and blending calculations, including AA downsampling. For box filter downsampling, you take the sum of the color values per sample times its area, so you get the total amount of photons for each pixel. All operations on colors that somehow simulate physical behavior should be performed in linear color space.

However, our perception is not linear which means storing an image in 8 bit per channel fixed point lRGB wastes too many bits for the bright colors, while you get banding in dark areas. To solve that you can either use an FP16 representation (needs bandwidth), or store colors in sRGB color space (needs conversion to and from lRGB).

Non-linear tone mapping is a special case that tries to introduce perception characteristics into this model. That's bound to raise problems, and I doubt there's a "correct" way of doing it. I'm not truly convinced tone-mapping should be non-linear at all.

When rendering or processing an image, you really can't take monitor response curve into account. There might even be no monitor attached.
 
Arjan, looking at your sinc on the van der Wolf reference image I notice that the "mid grey" (purely blurred fine-detail) is too bright. It should (shouldn't it :?: ) come out as R=G=B=127/128, but it's coming out as 161 (in gamma 2.2 space).
An average grey (i.e. 50:50 mix of white and black) should require a value of ~186 for a display system with a gamma of 2.2
 
While I realise the performance would be agonising at this point in history, is there any fundamental reason why you can't do perfect antialiasing of a 3D scene in the same way as you can for 2D drawings? Certainly it seems like it ought to be possible for polygon edges, although not for textures.

If you think about the 2D case for a moment.... If the pixels on the screen form a rectangular grid, then a theoretical line (say) 1 pixel wide is a long, thin rectangle overlayed on the pixel grid (at an angle). It's possible to calculate precisely how much of the area of each pixel falls within the boundary of the line-rectangle, and how much of each pixel falls outside it. The colour of the pixel is then determined by averaging the two coloured areas in a way that takes account of the gamma of the display. So if half of the pixel is supposed to be filled white and the other half black, and the display gamma is 2.2, the pixel should be filled in with grey-intensity of 186.

This is perfect antialiasing, the equivalent of super-sampling at an infinite resolution.

It gets more complicated as soon as you have more than one line pasing through the same pixel, because you then have to do depth-sorting, and some of the area of the pixel inside the first line may also lie inside the boundary of the second line. But, even so, it's still potentially possible to do antialiasing perfectly (so long as the display gamma is known).

In the 3D case you would "simply" ;) have to project all of the polygon edges into 2D lines (which you pretty much have to do anyway) and you could then do exactly the same calculation, and thus produce perfect antialiasing of polygon edges by calculating the exact area of each pixel that falls inside or outside each polygon.

To do this you would need to have a PowerVR-style deferred renderer which loads all of the polygons in the scene before figuring out which ones influence which pixel. And, while the calculation sounds horrendous, how many polygon edges actually intersect within a typical pixel? Surely not more than "a few"? :)

Of course, this approach wouldn't do anything for texture-aliasing, becauses textures are defined as raster-graphics rather than vector-graphics. But if we make the polygons small enough then we can get rid of textures altogether anyway. :)

Is it possible we might see an approach like this one day?

(PowerVR was rather good for super-sampling antialiasing, as I recall; if you took a 4x4 tile and made it responsible for generating only 1 pixel, you had 16x super-sampled AA; and the performance degraded only linearly because of a deficiency in fill-rate; you didn't get the increase in frame- or Z-buffer memory bandwidth usage that traditional architectures needed when supersampling).
 
This is perfect antialiasing, the equivalent of super-sampling at an infinite resolution.
What you describe is called a box filter. It is hardly "perfect" - it provides an exact average of a rectangular region, but it is entirely possible to produce visually better results than what a box filter can do - take a look at the image series posted by stepz eariler in this thread for some examples (they use 16x supersampling: the 'box' image still has fairly visible aliasing that is rather effectively removed in e.g. 'lanczos'; this aliasing is a limitation of the box filter rather than the input content, and cranking the degree of supersampling up to, say, 10000x won't fix it.)
 
While I realise the performance would be agonising at this point in history, is there any fundamental reason why you can't do perfect antialiasing of a 3D scene in the same way as you can for 2D drawings? Certainly it seems like it ought to be possible for polygon edges, although not for textures.
.....
It gets more complicated as soon as you have more than one line pasing through the same pixel, because you then have to do depth-sorting, and some of the area of the pixel inside the first line may also lie inside the boundary of the second line. But, even so, it's still potentially possible to do antialiasing perfectly (so long as the display gamma is known).
To do what you describe, you would have to clip "every" polygon against every other polygon that was passing though the pixel to obtain the truly visible regions of each polygon. After that, you might still have to resort to some form of sampling (within each region) for texture/shading calculations.

Finally, convolving those small areas with something other than a box filter would also be challenging.

I think you're 100% correct in saying "performance would be agonising".:???:
 
Why box filter isn't perfect...

A 1/4 pixel wide blue line on a white background.

Left: zoomed view of the line on the pixel grid
Middle: zoomed view of the pixel colors resulting from box filtering
Right: without zoom

Image is in sRGB space. Colors were averaged in linear space (see description in the post above) and converted to sRGB. Judge for yourself.
 

Attachments

  • thinline.png
    thinline.png
    2.4 KB · Views: 44
To demonstrate box filtering versus other filter types, I have prepared three small animations, which is the same sequence of frames downfiltered with three different filters (64x supersampling with an ordered 8x8 grid, gamma-correct downsampling):

Box:


Lanczos2:


Gaussian:


The object is a line that is 1.5 pixels wide at the left end and gradually narrowing towards 0 pixels at the right end.
 
Super sampling filters point samples. What I'd love to see is actually computing the exact area a polygon covers in a rectangular pixel. 8x8 super sampling with a box filter doesn't come close to that, because for a near-horizontal polygon (as presented by arjan) it can jump between say 4x8 to 5x8 fragments instantly.

256x256 super sampling with a box filter would be close enough. :D But really clipping the polygon to pixel edges and computing the remaining area would probably be more efficient at that point...
 
256x256 super sampling with a box filter would be close enough. :D But really clipping the polygon to pixel edges and computing the remaining area would probably be more efficient at that point...

Well, here is the Box filter with 8x horizontal and 128x :!: vertical supersampling. So now, instead of jumping between 4/8 and 5/8, it will jump between something like 72/128 and 73/128.

 
Arjan,

Can you describe how you are doing your Gaussian and Lanczos2 filters?

Thanks.
 
Arjan,

Can you describe how you are doing your Gaussian and Lanczos2 filters?

Thanks.

The Lanczos2 filter is done as described in the wikipedia article on the subject. The filter, as graphed there, has a width of 4 pixels; since I am doing 8x downsampling, the filter is stretched out to a 32-tap convolution filter - that is, it performs a weighted average of 32 samples along each axis. For the Lanczos filter, some of the weights are negative.

For the Gaussian filter, I'm using a Gaussian Curve as the filter function, with the actual value for each filter tap being exp(-2*x*x) where x is the distance in pixels from the center of the filter (again, 8x downsampling means 1 sample = 1/8 pixel); the filter is truncated at +/-3 pixels (+/- 24 samples) distance from the filter center. Unlke Lanczos, all the filter weights are positive.

For all filtering functions, I also do a linearRGB to sRGB transform after the actual filtering, so as to get a linear response when the result is displayed on an sRGB device (which, to a relatively close approximation, the majority of PC monitors are, unless their 'brightness' is misconfigured like hell).
 
Well, here is the Box filter with 8x horizontal and 128x :!: vertical supersampling. So now, instead of jumping between 4/8 and 5/8, it will jump between something like 72/128 and 73/128.
Thanks. Interesting result. On my TFT it doesn't look any better than the 8x8 box filter...

Excuse my skepticism, but I find it hard to accept this is correct. I would expect a box filter with a (very) high number of samples to produce good results. Are you sure the hardware/software you used for generating this animation can handle this high resolution with sub-pixel precision? How precise is the gamma correction? Does the box filter work in one step or is it implemented as a number of 2x2 downsamples?

Current hardware uses a box filter for anti-aliasing, and it often looks better than this...
 
Thanks. Interesting result. On my TFT it doesn't look any better than the 8x8 box filter...
I did not really notice much of a difference on my own monitor either.
Excuse my skepticism, but I find it hard to accept this is correct. I would expect a box filter with a (very) high number of samples to produce good results. Are you sure the hardware/software you used for generating this animation can handle this high resolution with sub-pixel precision? How precise is the gamma correction? Does the box filter work in one step or is it implemented as a number of 2x2 downsamples?
The animations are generated with a software renderer, using FP32 for all filtering calculations and rasterization arithmetics. The box filter is implemented as a separable filter (filter horizontally first, vertically second) with intermediate results also stored as FP32. The gamma correction itself is slightly less precise, using a 4096-entry lookup table (still 12 bits of linear-RGB precision, though); the gamma function used to generate the table is the standard sRGB function. (The table is used only after filtering; intermediate results are all linear-RGB.)
Current hardware uses a box filter for anti-aliasing, and it often looks better than this...
If you have done any "control-panel"-style tweaks to your monitor or graphics card gamma (or if they are misconfigured in the first place - you can find some test patterns here to check with) my animations will look wrong and probably quite bad indeed. If you haven't, I am actually rather curious as to what hardware you consider to be giving a better result.
 
Excuse my skepticism, but I find it hard to accept this is correct. I would expect a box filter with a (very) high number of samples to produce good results.
There are cases where it doesn't produce good results. Thin lines are one example. Look at the image I attached in the post above. Thin lines result in jagged edges with a box filter, no matter how many samples you take (my example uses "perfect" coverage).

A box filter ignores sample location. Whether a sample is in the top left corner of a pixel or in its center, it is treated exactly the same. If you look at it the other way round, it means that some samples spread their influence equally in all directions, and some spread their influence only in one direction (to the area below and to the right, for example).
This can also be seen with mipmap generation using a box filter. If you have a square white texture and add a black dot slightly to the right of the center, you can observe that the black dot "spreads" to the right in smaller mip levels, but not to the left at all (except for the very last mip level), despite being very close to the middle. If you move the dot just slightly to the left, you'll get the complete opposite.

So if you have a moving object that is smaller than one pixel (in one dimension at least), you will see no change as long as the object stays completely inside a pixel. But when the object reaches the edge of the pixel, it will rather suddenly "jump" to the next pixel.
 
Its nice to see how Lanczos2 and guassian in the vertical position always effect 4 pixels vertically. Frankly I consider an image where the line effect pixels is doesn't touch to be incorrect image.

I'd debate the perfect coverage is aliasing free since it isn't sampling as measure continuously.
 
Last edited by a moderator:
Back
Top