This commit is contained in:
Miloslav Ciz 2024-05-02 22:35:34 +02:00
parent fab11be42b
commit 1cfa0787d3
16 changed files with 1922 additions and 1760 deletions

View file

@ -14,4 +14,145 @@ Note that the word *anti* in antialising means that some methods may not prevent
- **[MIP mapping](mipmap.md)**: Way of preventing aliasing in rendering of scaled-down [textures](texture.md) by having precomputed scaled-down antialiased versions of it.
- **[anisotrpic filtering](anisotropic_filtering.md)**: Improved version of MIP mapping.
- **[motion blur](motion_blur.md)**: Temporal antialiasing in video, basically increasing the number of samples in the time domain.
- ...
- ...
## Code Example
Here is a quite primitive example of [supersampling](supersampling.md) (one of the simplest antialiasing methods) in [C](c.md). We will draw a two dimensional "fish eye" distorted [sine](sin.md) pattern (similar to checkerboard pattern but smooth, to show that aliasing happens even with smooth images!) that gets smaller towards the edges, i.e. the pattern is quite big in the center but near the edges the brightness oscillates with subpixel frequency which will lead to aliasing. First we'll draw the pattern as is, i.e. taking one sample per each pixel, letting aliasing happen; then we'll try to suppress aliasing by taking multiple samples per each pixel and averaging them -- this effectively increases our sampling frequency. It is basically equivalent to drawing the picture in increased resolution and then smoothly downsizing it (but in practice we don't do this as we'd waste a lot of [RAM](ram.md) on storing the big resolution picture, which is completely unnecessary). Let's see the code.
```
#include <stdio.h>
#include <math.h>
#define W 64 // image width
#define H 32 // image height
#define S 9.0 // pattern scale
const char palette[] = "#OVaxsflc/!;,.- ";
double sample(double x, double y) // function sampling our pattern
{
return sin(S / (x < 0 ? (x + 1) : (1 - x))) *
sin(S / (y < 0 ? (y + 1) : (1 - y)));
}
char doubleToChar(double x) // maps <-1,1> brightness to palette character
{
int i = ((x + 1) / 2.0) * 15;
return palette[i < 0 ? 0 : (i > 15 ? 15 : i)];
}
void draw(int antialiasSamples)
{
#define OFFSET 0.0001 // this tiny offset makes the pictures a bit nicer
double
x, y = -1 + OFFSET,
stepX = 2.0 / W,
stepY = 2.0 / H;
double
aaStepX = stepX / antialiasSamples,
aaStepY = stepX / antialiasSamples;
for (int j = 0; j < H; ++j) // draw rows
{
x = -1 + OFFSET;
for (int i = 0; i < W; ++i) // draw columns
{
double r = 0;
for (int l = 0; l < antialiasSamples; ++l)
for (int k = 0; k < antialiasSamples; ++k)
r += sample(x + k * aaStepX,y + l * aaStepY);
putchar(doubleToChar(r / (antialiasSamples * antialiasSamples)));
x += stepX;
}
y += stepY;
putchar('\n');
}
}
int main(void)
{
draw(1);
putchar('\n');
draw(8);
return 0;
}
```
Here are the results, first picture is without any antialiasing, second one with 8x8 supersampling (i.e. taking 64 samples per pixel):
```
c//xfs/c!fcs/lxf//cfssflc/!//cllfllc//!/clfssfc//fxl/scf!c/sfscl
/,!Vsa;c,x!a,cVs;,cxVVxl!;,,;/cfsfc/;,,;!lxVVxc,;sVc,a!x,/;afVcc
fss/c/sfscf/sl/cssfc//clfssssfllcllfssssflc//cfssc/ls/fcsfs/l/fl
/,;OsV;/.x!V,cOs;,/xVVxl!,.,;!cfsfc!;,.,!lxVVx/,;sOc,V!x./;VfV/c
!-,#sO./-a;O-c#x.-/a##al;.--.;cfxfc;.--.;la##a/-.x#c-O;a-/.#f#/c
c!!afx!c;s/x!caf!!csaxsl/!;;!/clslc/!;;!/lsxasc!!fac!x/s;c!xfacl
/.,#sO,/-a!O.c#s,./a#Oxl;.-.,!cfxfc!,.-.;lxO#a/.,s#c.O!a-/,Of#/c
x#V-/.Os#;a.#f-!O#s;--;laO##Oafc!cfaO##Oal;--;s#O!-f#.a;#sO-c-sf
/,;OsV;/.x!V,cOs;,/xVVxl!,.,;!cfsfc!;,.,!lxVVx/,;sOc,V!x./;VfV/c
c/csfs/c/fcs/lsf//cfssflc////cllfllc////clfssfc//fsl/scf/c/slscl
s#V-/.Vs#;a.#f-/V#s;--;laO##Vafc!cfaO##Oal;--;s#V!-f#.a;#sO.c-sf
fxx;c!xfa/s!xf;cxaf/;!/lsxaaxsfc/lfsxaaxsl/!;/faxc;fx!s/afx!c;fl
c;!afx!c;s/x;caf!;csaasl/!;;!/cfsfc/!;;!/lsaasc;!fac;a/s;c!afacl
!-,#sO./-a;O-c#x.-/a##al;.--.;cfxfc;.--.;la##a/-.x#c-#;a-/.#f#/c
/,;OsV;/.x!V,cOs;,/xVVxl!,.,;!cfsfc!;,.,!lxVVx/,;sOc,V!x./;VfV/c
lccflfclcfcfclflcclfffflccccccllfllcccccclfffflcclflcfcfclcflfll
fxs!c!sfx/s!xl!csxf/!!/lsxxxsfflclffsxxxsl/!!/fxsc!fx!s/xfs!c!fl
lccflfclcfcfclflcclfffflccccccllfllcccccclfffflcclflcfcfclcflfll
/,;OsV;/.x!V,cOs;,/xOVxl!,.,;!cfsfc!;,.,!lxVVx/,;sOc,V!x./;VfV/c
!-,#sO./-a;O-c#x.-/a##al;.--.;cfxfc;.--.;la##a/-.x#c-#;a-/.#f#/c
c;!afx!c;s/x;caf!;csaasl/!;;!/cfsfc/!;;!/lsaasc;!fac;x/s;c!afacl
fax;c!xfa/s!xf;cxaf/;!/lsxaaxsfc/cfsxaaxsl/!;/faxc;fx!s/afx!c;fl
s#V-/.Vs#;a.#f-/V#s;--;laO##Vafc!cfaV##Oal;--;s#V!-f#.a;#sO.c-sf
c/csfs/c/fcs/lsf//cfssflc////cllfllc////clfssfc//fsl/scf/c/slscl
/,;OsV;/.x!V,cOs;,/xVVxl!,.,;!cfsfc!;,.,!lxVVx/,;sOc,V!x./;VfV/c
x#V-/.Os#;a.#f-!O#s;--;laO##Oafc!cfaO##Oal;--;s#O!-f#.a;#sO-c-sf
/.,#sO,/-a!O.c#s,./a#Oxl;.-.,!cfxfc!,.-.;lxO#a/.,s#c.O!a-/,Of#/c
c;!afx!c;s/x!caf!;csaxsl/!;;!/cfsfc/!;;!/lsxasc;!fac!x/s;c!xfacl
!-,#sO./-a;O-c#x.-/a##al;.--.;cfxfc;.--.;la##a/-.x#c-O;a-/.#f#/c
/,;OsV;/.x!V,cOs;./xOVxl!,..;!cfsfc!;..,!lxVOx/.;sOc,V!x./,VfO/c
fffclcflfcfcflccfflcccclffffffllcllfffffflcccclffcclfcfcflfclcll
c/csfs/c/fcs/lsf//cfssflc////cllfllc////clfssfc//fsl/scf/c/slscl
llllllllllllflclfflcccllfffffllllllfffffllccclfflccflcflllllllll
llllllllllllflclfflcccllfffffllllllfffffllccclfflccflcflllllllll
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
llllllllllllclflcclfffllccccclllllllccccllffflcclflclfllllllllll
lllllllllfclfcclfflcccllfffffllllllfffffllccclfflccflcfcllllllll
lllllllccs/lx/!fxsl!!!cfsxxxsflcclfsxxxxfc/!!csxf!/sf/scllfllcll
ffflllcff!xl,xVc.;fVOas/;..,;/lssl/;,..;/faOVf;./aa;ca;sllcflflf
ccclllfccx!lV!,fOac,.,/saOOVasl//lsaVOOVsc;.,caOs,;af;a/llfcfclc
ffflllcff!xl.xOc.,fV#Vs/,--.;/lssl/;.--,/fV#Of;-/Va,ca;xflcfcflf
llllllllllllflclflllcllllfffllllllllfffllllccllfllllllllllllllll
ccclllfcca!lO!.f#Vc.-./sV##OVxl//lsaO##Vsc,-.cV#s,;Vf,a!clscfclc
lllllllllfclsc/lsflc/ccffsssfflcclffsssfflc//lfsfccflcfcllllllll
ffflllcff!sl;sac,;laVafc;,,,!/lfsl/!;,,;/faVaf!,/ax;cx!sllcflflf
ffflllcff;xl.aOc-,fO#Os/,--.,!lssl/,.--,/fV#Of,-/OV,cV,xfl/fcflf
ffflllcff/sl;sac;!laVafc!,,;!/lffl/!;,,;/fxVaf!,cax!cx!sllcflflf
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
lllllllllfclsc/lssl///cfssssfflcclffssssfl///lfsf/cslcfcllllllll
lllllllllcfl/fsl//lsssfc/////clfflcc////clssslc/csf/lfcfllclllll
ffflllcff!xl,xVc.;fVOVs/;...;/lssl/;,..,/faOVf;./Va,ca;sllcfcflf
ffflllcff!xl.xOc-,fV#Vs/,--.,!lssl/;.--,/fV#Of;-/Va,ca;xfl/fcflf
lllllllllcfl/fsl//lsssfc/////clfflc/////clsssl//css/ls/fllclllll
ccclllfccx/la/;fVal;,;cfaVVVxslc/lsxaVVasc;,;cxVs;!af!x/llfclclc
ccclllfccx!lV!,fOac,.,/saOOVasl//lsaVOOasc;.,caOs,;af;a/llfclclc
ffflllcff/sl;sac;!laVxfc!;,;!/lfflc!;,;!/fxVaf!;cxx!cx!sllcllflf
lllllllllcfl/fsl//lsssfc////cclfflcc////clssslc/csf/lfcfllllllll
cccllllccs/la/;faxl!;!cfxaVaxslcclfxaaaxsc!;;cxaf!!xf!x/llfllclc
lllllllllcflcfflcclfffllcccccllllllcccccllffflcclffclfclllllllll
fffllllff/sl;sac;!lxaxfc!;,;!/lfflc!;;;!/fxaaf!;cxx!cx!sllcllflf
llllllllllllllllflllcllllffflllllllllffllllclllfllllllllllllllll
lllllllllcflcfflcclfsfllc//cccllllccc//cclfsflc/lffclfcfllllllll
llllllllllllllflclllfllllcccllllllllcccllllflllcllllllllllllllll
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
```
It's a bit harder to see with [ASCII art](ascii_art.md) but still it is noticeable even here (the more it will be seen in "real" graphics) -- the first version of the image is much noisier, despite the underlying pattern itself being smooth, just sampled differently. Notice the images really significantly differ near the edges where aliasing appears, the center is basically the same -- here we can spot an obvious weakness of supersampling: that we have wasted computational power on supersampling the part which didn't need it. You can think of ways how this could be improved. Also think for example about placing our samples within one pixel differently than in a uniform grid -- what effect would it have? Here are things for you to explore.