Sampling

Når man skal rendere enkelte effekter som kræver tilfældige punkter bruger man sampling. Eksempler er når et texture skal nedskaleres, når et billede skal oversamples (flere rays per pixel) for at undgå antialiasing, når depth-of-field sender flere rays igennem en forvridende linse, når photoner skal reflekteres og når der en ray deles op og skal reflekteres i flere retninger ved gloss-effekter. I alle filfælde har man brug for en samling tilfældige punkter i [0,1]×[0,1] som dækker hele områder jævnt og hvor punkter ikke klumper for meget sammen. Det første kaldes også en uniform fordeling og det andet en god blue-noise karakteristik. Et tilfældigt punkt i [0,1]×[0,1] kan via polære koordinater mappes til et punkt på en kugle med radius een, hvilke også kan ses som en tilfældig retnings-vektor eller ray.

En helt tilfældig uniformt fordelt række punkter kaldes også en Monte-Carlo-sekvens. En række punkter hvor man har slækket på det uniforme krav til gengæld for at punkter ikke klumper for meget sammen, men tæt på, kaldes en quasi-Monte-Carlo-sekvens. Man er interesseret i at punkter ikke klumper sammen, da man så ender med at skyde mange rays i samme næsten retning, hvilket er spildt tid.

rand()

Følgende billede viser 2127 punkter fundet på 0.04 sekund, via systems random-funktion. Disse punkter er uniformt fordelte, men klumper sammen. Sådanne klumper er spild af tid, da de resulterer i mange rays i samme retning.

Dart-throwing

Den tæt-på-perfekte fordeling er Poissons diskfordeling. I denne gælder det at alle punkter er uniformt fordelte og har en disk omkring sig hvor i ingen andre punkter ligger. Det er dog meget svært at genere sådan en samling punkter. Hidtil har man brugt en metode kaldet dart-throwing, hvor man finder uniformt fordelte tilfældige punkter og smider de punkter væk som ender i andre punkters disk. I nedenstående billede repræsenteres disse punkter og deres diske som kugler.

Dart-throwing fandt 1782 punkter på tiden 1:39.92, dvs. 1 minut og 40 sekunder. Punkterne er dog uniformt fordelte. For at kunne terminere opgiver Dart-throwing-metoden når den har smidt for mange punkter væk i streg. I dette tilfælde opgiver den når et nyt punkt ikke kan findes efter 10 millioner forsøg. Derfor er der huller i nedenstående billede.

Halton

Dart-throwing-metode er for langsom til at den effektivt kan bruges i raytracing. Jeg har derfor hidtil brugt en Halton-sekvens, som er en hurtig quasi-Monte-Carlo sekvens. Denne fordeler punkterne ret pænt --- med bedre fordeling end den helt tilfældige metode øverst, men ikke helt så god som Poissons diskfordeling via dart-throwing.

Halton-sekvensen udregnede 2127 punkter på 0.21 sekund.

Der findes andre quasi-Monte-Carlo sekvenser såsom Hammersley- og Sobol-sekvenser. Disse giver punkter som ikke er radikalt bedre end Halton-sekvensen. Samme gælder et jittered grid.

Boundary-sampling

Jeg har netop implementeret en helt ny algoritme kaldet Boundary-sampling. Den er nyligt opfundet af Daniel Dunbar and Greg Humphreys i deres artikel "A Spatial Data Structure for Fast Poisson-Disk Sample Generation" fra Proceedings of SIGGRAPH 2006. Det er en snedig metode til at finde punkter fordelt efter Poissons diskfordeling. Den efterlader desuden ikke huller, hvilket dart-throwing var nødt til for at holde tidsforbruget nede.

Nedenstående 2127 punkter er beregnet med denne metode. Det tog 0.27 sekund.