Aliasing and you
codinghorror.com
codinghorror.com
(In audio, there are other benefits to higher resolution, like latency; a 256-sample buffer adds 6ms at 44.1KHz, but only 1ms at 192KHz.)
But the buffer is there to allow you to gather data up before sending it across the pipe (physical or virtual) so you're not incurring latency you don't need to. Increasing the resolution of your data doesn't decrease latency, as you're just incurring that hit more frequently. If that worked, you could just do away with the buffer and send a continuous stream of data at whatever sampling rate you wanted.
But latency is critical for tracking through headphones, especially singers; a little bit of latency can screw up your pitch perception as well as your timing.
The primary reason to oversample in the audio world is two fold:
1) To avoid aliasing, which is a somewhat different issue from graphical aliasing. ADC conversion creates aliases of the primary signal lower in the frequency band. For example if we sample at 40khz we can resolve signals up to 20khz. If the input contains content higher than this frequency it will alias into the pass band.
For example a 24khz tone on the input would appear as a 16 khz tone, a 28khz tone would appear as a 12khz tone, all higher frequency content will mirror around the Nyquist-Shannon point. Now if it were possible to build a "brick wall" filter, that is. completely block anything above the Nyquist-Shannon point and completely pass everything under this point, there would be no issue. But, in practice, this type of filtering isn't possible. As a result if your sampling at 48khz and you want to accurately convert all content up to 20khz you have to play a balancing act. You either provided flat response to 20khz and accept that some aliasing will make it through, or deal with some reduced level(roll off) at the higher end of your desired spectrum and block all audible aliasing.
This is really the primary reason for oversampling for high fidelity content as we can push the anti-aliasing filter well above the audible spectrum, allowing us to get both flat response to 20khz and block all audible aliasing. It should also be said that this issue is becoming less and less and issue as ADC/DACs are now implementing digital filters which can get far closer to the ideal 'brick wall' than is reasonable with analog filtering.
2) At a deeper level, oversampling increases resolution. Note that resolution here means actual resolution, that is bit depth, which is in opposition to the use of the term in the parent post. An example would be modern Sigma-Delta ADC/DACs.
Its common to use a low resolution part, maybe only 1-4 bits and oversample at a higher rate. For example, if your target output is 48khz @ 24 bits, you can use a 20 bit ADC and sample at ~12.28Mhz and downsample (internally within the ADC/DAC, really just averaging) to get your desired output. In practice a part may only operate on 1-4 bits but sample, much, much faster to get the desired resolution.
As for upsampling for the purpose of signal processing, there are a limited number of algorithms where this is useful and upsampling in and of itself introduces issues that have to be dealt with. The reason for upsampling tends to have more to do with processing accuracy limitations created by computation than anything else. For example bi-quad filter coefficients at very low frequency, say 5-8hz can exhaust the available resolution of a 32bit float at 48khz where as it may be completely fine at 192khz. This can be an issue with a sub-sonic filter in a subwoofer for instance.
I understand the value of using 96KHz instead of 48KHz so you can have a gentler filter, at least in the days before digital filters (as you say), but don't you agree that there's no further advantage to 192KHz in that respect? Maybe I'm justifying 192KHz by saying that it's for cleaner processing, when the real reason is It's A Bigger Number.
I've never heard anyone use "resolution" to mean bit depth; in fact, I've always heard it used to specifically mean sample rate - e.g. 96KHz resolution, 24 bits. But I've never studied DSP programming - I have a plumber's understanding, not a fluid mechanics engineer's.
Also modern graphics cards do not give programmatic access to the z-buffer as the z-buffer format is often proprietary. Deferred shading based renderers often duplicate the z-value also into a texture.
Deferred rendering can render large number of dynamic, unshadowed lights very efficiently. It can be used as approximate global illumination technique.
Why is that? While techniques like FXAA are needed for deferred rendering due to the order of operations, I don't see why FXAA isn't acceptable on non-deferred renderers.
> Detecting edges on the depth buffer may sound as the solution until you realize that two planes at right angles has an edge between that can alias. The change there is in the normal and not the Z.
If you have two planes at a right angle to each other, you'd see that in the depth buffer. Imagine you're looking at a line of pixels and you're doing this on each pixel -- you'd look to see if the pixels on either side of the one you're on are trending in opposite directions from the current one, and know it's an edge.
> Also modern graphics cards do not give programmatic access to the z-buffer as the z-buffer format is often proprietary.
As far as I'm aware, all modern graphics cards allow you to render the depth buffer to texture just like the color buffer.
> Deferred rendering can render large number of dynamic, unshadowed lights very efficiently. It can be used as approximate global illumination technique.
Sure, but there's no reason you can't do post-AA using the RTT depth buffer and your composited color buffer.
FXAA is acceptable for the other techniques as well. However, MSAA is, in my opinion, a better technique as it uses supersampling at the edges and is already hardware assisted. FXAA's strength is that it is less expensive than MSAA memory and bandwidth wise. Both are a premium in deferred shading as you are using a 4x RBGA16 texture render target or something close to it :)
> If you have two planes at a right angle to each other, you'd see that in the depth buffer. Imagine you're looking at a line of pixels and you're doing this on each pixel -- you'd look to see if the pixels on either side of the one you're on are trending in opposite directions from the current one, and know it's an edge.
The question is can you get reliable edge detection with less number of texture look-ups on the z-buffer versus the RBG based edge detection?
> As far as I'm aware, all modern graphics cards allow you to render the depth buffer to texture just like the color buffer.
Not quite. You can render the z value to a texture, but that is done in the pixelshader and do not touch the hardware z-buffer used for z-fail/z-pass tests. It is this hardware z-buffer that is inaccessible, as it shares it memory with the stencil buffer which is used for stencil tests. Hence the proprietary format.
> Sure, but there's no reason you can't do post-AA using the RTT depth buffer and your composited color buffer.
See http://msdn.microsoft.com/en-us/library/windows/desktop/bb14...
> All render target surfaces used together must have the same bit depth but can be of different formats, unless the D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS cap is set.
As you can see, the bit depth restriction means that you would end up with 2x bandwidth usage with the z based edge detector, especially on the older hardware where you do not have the bandwidth to spare. It would be a different case if you can sample the hardware z-buffer.
This was true for Direct3D 9 but 10+ allow you to bind the depth/stencil buffer as a texture, although there is the caveat that you can't have it simultaneously bound as a texture and as a render target.
See "Reading the Depth-Stencil Buffer as a Texture" on this page: http://msdn.microsoft.com/en-us/library/windows/desktop/bb20...
The way it's working in my mind has about the same number of lookups as FXAA, but I'm honestly not sure how that'd pan out in practice. We'll see.
> As far as I'm aware, all modern graphics cards allow you to render the depth buffer to texture just like the color buffer. Not quite. You can render the z value to a texture, but that is done in the pixelshader and do not touch the hardware z-buffer used for z-fail/z-pass tests. It is this hardware z-buffer that is inaccessible, as it shares it memory with the stencil buffer which is used for stencil tests. Hence the proprietary format.
No need for the internal format, though -- raw depth buffers are A-OK.
> As you can see, the bit depth restriction means that you would end up with 2x bandwidth usage with the z based edge detector, especially on the older hardware where you do not have the bandwidth to spare. It would be a different case if you can sample the hardware z-buffer.
One thing to keep in mind is that yes, you're rendering it to texture and you incur some overhead there, but you don't have to pull that data back to the CPU so you're dependent on bandwidth between the GPU and its memory, not main memory. Sure, it's double the memory used there, but that's negligible from a bandwidth perspective. Also a good thing to note that you generally already have your depth buffer if you're doing deferred rendering, and you can do all the AA based on that, in theory.
However, the FXAA will have a clear win as it works over a partly transparent polygon. So you will have to combine both an RBG and z based to get the same result as an FXAA.
> you're dependent on bandwidth between the GPU and its memory, not main memory.
The bandwidth I was talking about was the older cards which do not have bandwidth or fill rate to keep 60fps with deferred shading, no AA. FXAA would be a candidate there if it is a pure RGB technique on the composited frame, especially as it is cheaper than MSAA.
Missed that one as I have been mostly playing around in DX9 and only a bit of DX10.
There is the case of the billboarded or partly transparent texture. The z-based edge methods will not work in these cases as you render them with z-write off. Meaning, atleast in those cases, FXAA is a clear winner over both MSAA and z-based edge detection.
Why do you say that FXAA is only relevant to deferred rendering?
If you have a deferred rendering setup, you'll have the depth buffer and the normal buffer (a floating point texture with normal vectors) available. These can be used to do edge detection for silhouette edges and non-silhouette sharp edges.
I don't know the details of modern anti aliasing techniques, but I'd guess that you can get the best edge detection using a combination of the color, depth and normal buffer. Whether you want to do this for anti aliasing is a different issue, a simple RGB edge detect may yield better results.
>> Also modern graphics cards do not give programmatic access to the z-buffer as the z-buffer format is often proprietary. Deferred shading based renderers often duplicate the z-value also into a texture.
This doesn't make any sense. The depth buffer may be internally stored in a compressed proprietary format, but it's still available to the programmer as a regular buffer or texture.
You have plenty of ways to access the depth buffer for reading. The depth buffer can be rendered into a texture (either as floating point or regular 24 bit integer), which can be read back in a shader. You can do regular lookups where you get back the depth value or a shadow lookup with percentage closer filtering.
The depth values can also be read back from the buffers (using glReadPixels in OpenGL) to be analyzed on the CPU (not feasible for anything realtime) or saved to disk or whatever.
If either the difference of the normal or the z-value is over a certain threshold you add some black color to the pixel to make the edge look thicker.
http://www.geforce.com/Active/en_US/shared/images/guides/the...
http://www.geforce.com/Active/en_US/shared/images/guides/the...
I know very little about this stuff but wouldn't using the depth buffer in addition to the current algorithm make it possible not to smooth over details like this?
Also there is software that automatically injects SMAA into your d3d9, d3d10 or d3d11 games: http://mrhaandi.blogspot.com/p/injectsmaa.html
Pulled directly from codinghorror comments, posted by: Mārtiņš Možeiko
Super-sampling: expensive[cpu]
As an aside, the FXAA touted in this blog post looks washed out and generally terrible.
Can it be used to make flash graphics and webgl lower load too?
For WebGL, you should be able to write the shaders and a multi-pass renderer framework that does the antialiasing. However, with WebGL, you're constrained to using somewhat simpler texture formats than you have available with a modern desktop. If you have to use 8 bit RGBA textures, you will probably suffer from color banding and other nasty artifacts compared to 16 bit floating point textures that are normally used on the desktop.
I hope this becomes standard on PS3 titles, it's painful seeing all those ragged edges on screen, knowing you have a few gigaflops of processing power sitting there, doing nothing :(
TIL.
It looks smoother and more focused: http://i.imgur.com/hsq84.jpg
Also it can't be done in-place (or can it?)