Hlavní navigace

Kouzla s kamerou potřetí, alias a antialiasing

27. 1. 2009
Doba čtení: 15 minut

Sdílet

V dnešní části seriálu o POV-Rayi si na dvou demonstračních příkladech ukážeme animovanou změnu směru primárních paprsků pomocí procedurálních textur (simulace objektů pod rozvlněnou hladinou). Také si řekneme, proč ve vykreslovaných scénách vzniká alias a jakým způsobem je možné jeho vliv potlačit.

Obsah

1. Ovlivnění primárních paprsků procedurálním vzorkem
2. První demonstrační příklad – animované ovlivnění primárních paprsků vzorkem „waves“
3. Druhý demonstrační příklad – animované ovlivnění primárních paprsků vzorkem „ripples“
4. Alias a antialiasing
5. Supersampling
6. Adaptivní nerekurzivní supersampling
7. Adaptivní rekurzivní supersampling
8. Obsah další části seriálu

1. Ovlivnění primárních paprsků procedurálním vzorkem

V předchozí části tohoto seriálu jsme si vysvětlili princip takzvané perturbace, neboli ovlivnění směrů primárních paprsků, které vycházejí z kamery přes projekční plochu do části prostoru vykreslované scény. Při standardním nastavení raytraceru je každý paprsek poslán jedním pixelem projekční plochy, která tvoří výsledný rastrový obrázek (jak si však řekneme v dalších kapitolách, primárních paprsků může jedním pixelem procházet více, ovšem jejich počátek leží vždy v kameře, tj. v případě perspektivní projekce primární paprsky vychází přímo z jejího středu). Ovšem směr těchto paprsků je možné ovlivnit nastavením atributu normal, podobně jako při modulaci normálových vektorů (bump mappingu). Pokud je atribut normal u kamery nastaven, prochází sice každým pixelem projekční plochy jeden paprsek (popř. více paprsků při využití antialiasingu), ovšem směr tohoto paprsku je změněn na základě aktuální hodnoty vypočtené z procedurálního vzorku či uživatelsky definované funkce specifikované v atributu normal.

povray4501

Obrázek 1: Primární paprsek vycházející z kamery, který při protnutí projekční plochy prochází středem pixelu, jehož barva se právě počítá.

Takový primární paprsek pak ve skutečnosti nevychází přímo z kamery, ale jiného místa prostoru (viz druhý obrázek, kde je naznačena jak původní pozice kamery location, tak i její zdánlivá pozice location' platná obecně pouze pro jeden primární paprsek). Velmi zajímavého – a mnohdy také užitečného – efektu lze dosáhnout průběžnou změnou parametrů procedurálního vzorku. Výsledkem může být například animace připomínající objekty umístěné pod rozvlněnou vodní hladinu či přímo deformace celého snímaného prostoru. V následujících dvou kapitolách si průběžnou (animovanou) změnu parametru či parametrů procedurálních vzorků tvořících vstup pro perturbaci primárních paprsků ukážeme na demonstračních příkladech. V obou příkladech je použito běžné perspektivní promítání, protože (alespoň v současné verzi POV-Raye) je perturbace podporována pouze pro kameru nastavenou na perspektivní projekci.

povray4502

Obrázek 2: Vlivem perturbace se směr primárního paprsku změní, podobně jakoby došlo k posunu kamery do jiného místa v prostoru. Ovšem pro každý pixel výsledného obrázku může být odchylka odlišná; záleží na hodnotě vypočtené pomocí procedurálního vzorku.

2. První demonstrační příklad – animované ovlivnění primárních paprsků vzorkem „waves“

V dnešním prvním demonstračním příkladu je ukázán způsob ovlivnění směrů primárních paprsků procedurálním vzorkem „waves“. S tímto vzorkem jsme se v tomto seriálu již několikrát setkali, jak při tvorbě procedurálních textur, tak i v části věnované modulaci normál (bump mappingu). Jméno tohoto vzorku přesně vystihuje obraz, který je jím generován – jedná se o vlny vycházející z deseti náhodně zvolených bodů. Tentokrát si ukážeme, jak je možné zdánlivě zdeformovat celý prostor snímané scény právě pomocí tohoto vzorku.

povray4503

Obrázek 3: První snímek animace. Deformace prostoru je prozatím minimální, pouze se zvlnil původně vodorovný horizont.

Ve scéně je umístěna kamera s nastavenou perspektivní projekcí. Kromě pozice kamery v prostoru a specifikace bodu, na který kamera míří, je uveden také atribut normal s procedurálním vzorkem „waves“. Jeden z parametrů tohoto vzorku – phase – je měněn v závislosti na aktuální hodnotě interní proměnné clock, která při tvorbě animací průběžně mění svoji hodnotu od nuly do jedné. Vliv procedurálního vzorku na charakter vykreslené scény je značný, jak se můžete sami přesvědčit po shlédnutí této animace. Na začátku a konci animace není zkreslení velké (směry primárních vektorů se mění jen minimálně), ovšem zhruba uprostřed animace dochází ke značným deformacím celého prostoru.

povray4504

Obrázek 4: Snímek z první třetiny animace. Zdánlivá deformace prostoru je již značná, ovšem stále lze rozeznat původní tvar objektů.

Animace i všechny čtyři snímky byly vytvořeny pomocí tohoto zdrojového kódu:

// ------------------------------------------------------------
// První demonstrační příklad - vykreslení souřadných os,
// podkladové roviny a implicitní plochy. Nastavení
// perspektivního promítání s animovanou změnou paprsků
// vycházejících z kamery. Změna paprsků je ovlivněna
// procedurální texturou "waves".
//
// rendering lze spustit příkazem:
// povray +W320 +H240 +B100 +KFF100 +FN +D +Icamera1.pov
// ------------------------------------------------------------

// globální nastavení parametrů scény
global_settings
{
    assumed_gamma 2.2
    max_trace_level 5
}

// načtení všech potřebných externích souborů
#include "colors.inc"
#include "stones.inc"
#include "glass.inc"

// nastavení kamery (pozorovatele)
camera
{
    perspective
    sky +y                               // natočení kamery ve směru osy y
    location  <30.0, 55.0, -30.0>        // pozice kamery v prostoru
    look_at   <15.0, 5.0, 15.0>          // pohled kamery - střed obrázku
    normal                               // ovlivnění směru paprsků
    {                                    // které vychází z kamery
        waves                            // typ procedurálního vzorku
        frequency 0.2                    // nastavení frekvence opakování
        phase clock                      // změna fáze - základ animace
        scale 0.3                        // změna měřítka
    }
}

// tři světelné zdroje
light_source
{
    <-30, 50,  20>                       // pozice prvního světelného zdroje
    color White                          // barva světla
}

light_source
{
    < 31, 50, -20>                       // pozice druhého světelného zdroje
    color White                          // barva světla
}

light_source
{
    < 32, 50, 20>                        // pozice třetího světelného zdroje
    color LightGray                      // barva světla
}

// podkladová rovina
plane
{
    y, -15
    texture
    {                                    // textura - vlastnosti povrchu
        pigment
        {                                // šachovnicová textura
            checker                      // vyvedená ve stupních šedi
            color rgb <0.3, 0.3, 0.3>
            color rgb <0.5, 0.5, 0.5>
        }
        finish
        {                                // odlesky a odrazy na povrchu
            diffuse 0.7
            reflection 0.2
        }
        scale 10
    }
}

// X-ová osa
union
{
    // šipka
    cone
    {
        <0,0,0>,1,
        <25,0,0>,1
    }
    cone
    {
        <25,0,0>,1,
        <27,0,0>,5
    }
    cone
    {
        <27,0,0>,5,
        <35,0,0>,0
    }
    // X
    sphere
    {
        <35,5,0>, 1
    }
    sphere
    {
        <42,5,0>, 1
    }
    sphere
    {
        <35,5,10>, 1
    }
    sphere
    {
        <42,5,10>, 1
    }
    cone
    {
        <35,5,0>,1,
        <42,5,10>,1
    }
    cone
    {
        <35,5,10>,1,
        <42,5,0>,1
    }
    texture
    {
        pigment                          // barva povrchu
        {
            color red 1.0
        }
        finish
        {                                // odlesky a odrazy na povrchu
            diffuse 0.7
            phong 1                      // velikost a síla odlesků
            phong_size 30
            reflection 0.0
        }
    }
}

// Y-ová osa
union
{
    // šipka
    cone
    {
        <0,0,0>, 1,
        <0,25,0>, 1
    }
    cone
    {
        <0,25,0>, 1,
        <0,27,0>, 5
    }
    cone
    {
        <0,27,0>, 5,
        <0,35,0>, 0
    }
    // Y
    sphere
    {
        <5,35,10>, 1
    }
    sphere
    {
        <12,35,10>, 1
    }
    sphere
    {
        <8.5,35,0>, 1
    }
    cone
    {
        <8.5,35,5>, 1,
        <5,35,10>, 1
    }
    cone
    {
        <8.5,35,5>, 1,
        <12,35,10>, 1
    }
    cone
    {
        <8.5,35,5>, 1,
        <8.5,35,0>, 1
    }
    texture
    {
        pigment                          // barva povrchu
        {
            color green 1.0
        }
        finish
        {                                // odlesky a odrazy na povrchu
            diffuse 0.7
            phong 1                      // velikost a síla odlesků
            phong_size 30
            reflection 0.0
        }
    }
}

// Z-ová osa
union
{
    // šipka
    cone
    {
        <0,0,0>, 1,
        <0,0,25>, 1
    }
    cone
    {
        <0,0,25>, 1,
        <0,0,27>, 5
    }
    cone
    {
        <0,0,27>, 5,
        <0,0,35>, 0
    }
    // Z
    sphere
    {
        < 12,-5, 25>, 1
    }
    sphere
    {
        < 5, -5, 25>, 1
    }
    sphere
    {
        < 12, -5, 35>, 1
    }
    sphere
    {
        < 5, -5, 35>, 1
    }
    cone
    {
        <12,-5,35>, 1,
        <5,-5,25>, 1
    }
    cone
    {
        <12,-5,35>, 1,
        <5,-5,35>, 1
    }
    cone
    {
        <12,-5,25>, 1,
        <5,-5,25>, 1
    }
    texture
    {
        pigment                          // barva povrchu
        {
            color blue 1.0
        }
        finish
        {                                // odlesky a odrazy na povrchu
            diffuse 0.7
            phong 1                      // velikost a síla odlesků
            phong_size 30
            reflection 0.0
        }
    }
}

blob
{                                        // definice implicitní plochy s využitím původní syntaxe
    threshold 0.6                        // hraniční hodnota
    component 1.0, 1.0, < 0.750,  0, 0>       // prvek kostry: síla, poloměr, souřadnice v prostoru
    component 1.0, 1.0, <-0.375,  0.64952, 0> // druhý prvek kostry
    component 1.0, 1.0, <-0.375, -0.64952, 0> // třetí prvek kostry

    texture
    {
        pigment
        {
            color red 1 green 1 blue 0   // barva materiálu povrchu implicitní plochy
        }
        finish
        {                                // optické vlastnosti materiálu povrchu
            ambient  0.2
            diffuse  0.4
            specular 0.6
            phong    0.6
            phong_size 60
            reflection 0
        }
    }
    scale 10
    translate <20, 20, 20>
}

// ------------------------------------------------------------
// finito
// ------------------------------------------------------------ 
povray4505

Obrázek 5: Snímek ze druhé třetiny animace. Deformace prostoru dosáhla svého maxima.

povray4506

Obrázek 6: Poslední snímek animace se do značné míry podobá snímku prvnímu – animaci je možné promítat ve smyčce.

3. Druhý demonstrační příklad – animované ovlivnění primárních paprsků vzorkem „ripples“

Druhý demonstrační příklad nejlépe charakterizuje animace, která je pomocí něho vytvořena. Cílem tohoto příkladu bylo navodit dojem scény umístěné pod vlnící se vodní hladinu, přičemž postupně dochází ke zklidnění vln. Požadovaného efektu bylo dosaženo pomocí procedurálního vzorku „ripples“, jehož vliv (tj. míra změny směru primárních paprsků) postupně klesá a současně se mění i fáze vln. Tento efekt je zajištěn následujícím fragmentem kódu:

    normal                               // ovlivnění směru paprsků
    {                                    // které vychází z kamery
        ripples 0.25 * (1 - clock)       // typ procedurálního vzorku
        frequency 8                      // nastavení frekvence opakování
        phase 3.14 * clock               // změna fáze - základ animace
    } 
povray4507

Obrázek 7: První snímek animace – maximální deformace vlivem procedurálního vzorku.

V posledním snímku animace bude hodnota interní proměnné clock rovna jedné, proto bude výraz 0.25*(1-clock) nulový a nedojde tedy k žádnému ovlivnění směru primárních paprsků.

povray4508

Obrázek 8: Snímek z první třetiny animace.

Následuje výpis úplného zdrojového kódu druhého demonstračního příkladu:

// ------------------------------------------------------------
// Druhý demonstrační příklad - vykreslení souřadných os,
// podkladové roviny a implicitní plochy. Nastavení
// perspektivního promítání s animovanou změnou paprsků
// vycházejících z kamery. Změna paprsků je ovlivněna
// procedurálním vzorkem "ripples".
//
// rendering lze spustit příkazem:
// povray +W320 +H240 +B100 +KFF100 +FN +D +Icamera2.pov
// ------------------------------------------------------------

// globální nastavení parametrů scény
global_settings
{
    assumed_gamma 2.2
    max_trace_level 5
}

// načtení všech potřebných externích souborů
#include "colors.inc"
#include "stones.inc"
#include "glass.inc"

// nastavení kamery (pozorovatele)
camera
{
    perspective
    sky +y                               // natočení kamery ve směru osy y
    location  <30.0, 55.0, -30.0>        // pozice kamery v prostoru
    look_at   <15.0, 5.0, 15.0>          // pohled kamery - střed obrázku
    normal                               // ovlivnění směru paprsků
    {                                    // které vychází z kamery
        ripples 0.25 * (1 - clock)       // typ procedurálního vzorku
        frequency 8                      // nastavení frekvence opakování
        phase 3.14 * clock               // změna fáze - základ animace
    }
}

// tři světelné zdroje
light_source
{
    <-30, 50,  20>                       // pozice prvního světelného zdroje
    color White                          // barva světla
}

light_source
{
    < 31, 50, -20>                       // pozice druhého světelného zdroje
    color White                          // barva světla
}

light_source
{
    < 32, 50, 20>                        // pozice třetího světelného zdroje
    color LightGray                      // barva světla
}

// podkladová rovina
plane
{
    y, -15
    texture
    {                                    // textura - vlastnosti povrchu
        pigment
        {                                // šachovnicová textura
            checker                      // vyvedená ve stupních šedi
            color rgb <0.3, 0.3, 0.3>
            color rgb <0.5, 0.5, 0.5>
        }
        finish
        {                                // odlesky a odrazy na povrchu
            diffuse 0.7
            reflection 0.2
        }
        scale 10
    }
}

// X-ová osa
union
{
    // šipka
    cone
    {
        <0,0,0>,1,
        <25,0,0>,1
    }
    cone
    {
        <25,0,0>,1,
        <27,0,0>,5
    }
    cone
    {
        <27,0,0>,5,
        <35,0,0>,0
    }
    // X
    sphere
    {
        <35,5,0>, 1
    }
    sphere
    {
        <42,5,0>, 1
    }
    sphere
    {
        <35,5,10>, 1
    }
    sphere
    {
        <42,5,10>, 1
    }
    cone
    {
        <35,5,0>,1,
        <42,5,10>,1
    }
    cone
    {
        <35,5,10>,1,
        <42,5,0>,1
    }
    texture
    {
        pigment                          // barva povrchu
        {
            color red 1.0
        }
        finish
        {                                // odlesky a odrazy na povrchu
            diffuse 0.7
            phong 1                      // velikost a síla odlesků
            phong_size 30
            reflection 0.0
        }
    }
}

// Y-ová osa
union
{
    // šipka
    cone
    {
        <0,0,0>, 1,
        <0,25,0>, 1
    }
    cone
    {
        <0,25,0>, 1,
        <0,27,0>, 5
    }
    cone
    {
        <0,27,0>, 5,
        <0,35,0>, 0
    }
    // Y
    sphere
    {
        <5,35,10>, 1
    }
    sphere
    {
        <12,35,10>, 1
    }
    sphere
    {
        <8.5,35,0>, 1
    }
    cone
    {
        <8.5,35,5>, 1,
        <5,35,10>, 1
    }
    cone
    {
        <8.5,35,5>, 1,
        <12,35,10>, 1
    }
    cone
    {
        <8.5,35,5>, 1,
        <8.5,35,0>, 1
    }
    texture
    {
        pigment                          // barva povrchu
        {
            color green 1.0
        }
        finish
        {                                // odlesky a odrazy na povrchu
            diffuse 0.7
            phong 1                      // velikost a síla odlesků
            phong_size 30
            reflection 0.0
        }
    }
}

// Z-ová osa
union
{
    // šipka
    cone
    {
        <0,0,0>, 1,
        <0,0,25>, 1
    }
    cone
    {
        <0,0,25>, 1,
        <0,0,27>, 5
    }
    cone
    {
        <0,0,27>, 5,
        <0,0,35>, 0
    }
    // Z
    sphere
    {
        < 12,-5, 25>, 1
    }
    sphere
    {
        < 5, -5, 25>, 1
    }
    sphere
    {
        < 12, -5, 35>, 1
    }
    sphere
    {
        < 5, -5, 35>, 1
    }
    cone
    {
        <12,-5,35>, 1,
        <5,-5,25>, 1
    }
    cone
    {
        <12,-5,35>, 1,
        <5,-5,35>, 1
    }
    cone
    {
        <12,-5,25>, 1,
        <5,-5,25>, 1
    }
    texture
    {
        pigment                          // barva povrchu
        {
            color blue 1.0
        }
        finish
        {                                // odlesky a odrazy na povrchu
            diffuse 0.7
            phong 1                      // velikost a síla odlesků
            phong_size 30
            reflection 0.0
        }
    }
}

blob
{                                        // definice implicitní plochy s využitím původní syntaxe
    threshold 0.6                        // hraniční hodnota
    component 1.0, 1.0, < 0.750,  0, 0>       // prvek kostry: síla, poloměr, souřadnice v prostoru
    component 1.0, 1.0, <-0.375,  0.64952, 0> // druhý prvek kostry
    component 1.0, 1.0, <-0.375, -0.64952, 0> // třetí prvek kostry

    texture
    {
        pigment
        {
            color red 1 green 1 blue 0   // barva materiálu povrchu implicitní plochy
        }
        finish
        {                                // optické vlastnosti materiálu povrchu
            ambient  0.2
            diffuse  0.4
            specular 0.6
            phong    0.6
            phong_size 60
            reflection 0
        }
    }
    scale 10
    translate <20, 20, 20>
}

// ------------------------------------------------------------
// finito
// ------------------------------------------------------------ 
povray4509

Obrázek 9: Snímek ze druhé třetiny animace. Zde již docházík postupnému zklidnění a menší míře deformace prostoru.

povray4510

Obrázek 10: V posledním snímku animace již k žádné deformaci prostoru nedochází.

4. Alias a antialiasing

Při renderingu scén, ve kterých jsou použity procedurální textury s jemným vzorkem nebo velmi malé objekty, se často můžeme setkat s nepříjemným jevem zvaným alias. Tento jev vzniká ve chvíli, kdy je vzorek textury jemnější než rozlišení výstupního obrázku. Procedurální textury jsou zadány matematickou funkcí typu f(x,y) či f(x,y,z), přičemž při renderingu dochází k vzorkování (samplingu) této textury – z původně spojité funkce jsou vybrány jen diskrétní vzorky, podobně jako při digitalizaci původně spojitého zvukového signálu. V případě, že frekvence původní matematické funkce představující základ procedurální textury je větší než vzorkovací frekvence (převrácená hodnota vzdálenosti jednotlivých vzorků), dojde k aliasu. Ten se na výsledném obrázku projeví vznikem nového vzorku s nižší frekvencí, který v původní funkci procedurální textury obsažen nebyl. Někdy se tento vzorek, který většinou představuje nežádoucí část obrazu, nazývá moaré. Přímo učebnicový příklad aliasu je zobrazen na jedenáctém obrázku. Kvůli perspektivě se jednotlivé dlaždice šachovnice postupně zmenšují a ve chvíli, kdy je jejich velikost menší než velikost jednoho pixelu (popř. vzdálenost mezi sousedními pixely, pokud za pixel považujeme bezrozměrný bod), dojde k podvzorkování a vzniku aliasu.

povray4511

Obrázek 11: Šachovnicová textura vykreslená POV-Rayem bez využití antialiasingu. V blízkosti horizontu jsou dlaždice tak malé, že se jich na jeden pixel mapuje několik a dochází k podvzorkování „signálu“ představovaného procedurální texturou šachovnice. Vzniká rušivý alias.

S aliasem se můžeme setkat i tehdy, když dochází k vykreslení malých objektů nebo objektů, jejichž části jsou po promítnutí do výsledného rastrového obrázku zhruba stejně velké či menší, než je plocha jednoho pixelu. Může se stát, že vlivem aliasu nebudou některé části těchto objektů viditelné, což je zvláště nepříjemné v animacích – malé části objektů se mohou v některých snímcích objevit a v jiných zase zmizet, což samozřejmě působí rušivě (nemusí se jednat jen o geometricky malé objekty, stejné problémy způsobí i relativně velká plocha, která je natočena ke kameře svou hranou – vždy záleží na velikosti objektu po promítnutí do výsledného obrázku). POV-Ray sice obsahuje, ostatně jako naprostá většina moderních raytracerů, prostředky, které slouží ke zmenšení vlivu aliasu, ovšem za cenu prodloužení doby výpočtu a také částečného rozmazání obrázku (odstranění aliasu totiž většinou znamená odstranění vyšších frekvencí, což není nic jiného než rozmazání). Tyto metody si popíšeme v dalším textu.

5. Supersampling

Naprostá většina obrázků v tomto seriálu vznikla renderingem, při němž byl povolený algoritmus adaptivního nerekurzivního supersamplingu. Co se pod tímto „vědeckým“ názvem skrývá? Nejprve si vysvětlíme slovo supersampling. Ten je založen na jednoduché myšlence: pokud alias nastává ve chvíli, kdy každým pixelem výsledného obrázku prochází pouze jeden primární paprsek, co kdyby se plocha pixelu uměle zmenšila tak, že jím bude procházet větší množství paprsků? (v tomto článku budeme poněkud nepřesně pixel považovat za elementární plošku a ne bezrozměrný bod) Zatímco bez použití supersamplingu je primární paprsek vrhán středem pixelu, prochází při zapnutí supersamplingu jedním pixelem čtyři, devět, šestnáct atd. paprsků pravidelně rozmístěných tak, aby tvořily mřížku s jemnější strukturou než je původní rastrová mřížka pixelů. Pro každý primární paprsek je samostatně spočítána barva a nakonec se barvy všech paprsků procházejících jedním pixelem zprůměrují. Tímto jednoduchým trikem se sice alias neodstraní, ale posune se k vyšším frekvencím, což má mj. za následek větší či menší rozmazání obrázku.

povray4512

Obrázek 12: Posunutí aliasu směrem k vyšším frekvencím díky použití adaptivního nerekurzivního supersamplingu. Alias sice zcela z obrázku nezmizel, ale projevuje se především až v blízkosti horizontu. Také došlo k rozmazání hran dlaždic.

6. Adaptivní nerekurzivní supersampling

Přímým využitím výše popsané metody se sice dá dosáhnout uspokojivých výsledků, ale mnohdy za cenu neúměrného prodloužení výpočtu celé scény. Při zapnutí supersamplingu volbou +A prochází každým pixelem až 3×3 paprsky, což by znamenalo, že se rendering celé scény devětkrát prodlouží. To je samozřejmě velká daň za lepší vizuální vzhled výsledného obrázku. Naštěstí je možné využít adaptivní supersampling, jehož princip spočívá v tom, že je vlastní supersampling použit pouze v těch místech obrázku, kde dochází k aliasu – jsou to místa s velkým kontrastem. Při použití adaptivního supersamplingu se nejprve – v prvním kroku – každým pixelem pošle pouze jeden primární paprsek a následně se provede porovnání barev dvou sousedních pixelů podle vzorce diff = abs(r1-r2) + abs(g1-g2) + abs(b1-b2). Jelikož se scéna vykresluje od horního obrazového řádku k řádku spodnímu a na každém řádku zleva doprava, počítá se rozdíl barev oproti pixelu nahoře a nalevo. Pokud je výsledná hodnota menší než mez zadaná parametrem +Ax.x (implicitně je dosazena hodnota 0,3), je pixel přímo vykreslen. Jestliže se však barvy příliš odlišují, je již použit supersampling, tj. pixelem se pošle větší množství primárních paprsků a následně se spočte jejich průměrná barva.

Podívejme se nyní na statistiku renderingu skutečného obrázku číslo třináct, ve kterém je použito větší množství procedurálních textur s ultrajemným vzorkem (vzorek je možné libovolně zvětšit bez ztráty detailů, takže vždy dochází k aliasu). Tuto statistiku vypisuje samotný POV-Ray po dokončení renderingu:

Render Statistics
Image Resolution 1000 x 999

Pixels:          1000000   Samples:         4117360   Smpls/Pxl: 4.12
Rays:            4117360   Saved:                 0   Max Level: 1/5 

Při renderingu byla použita volba +w1000 +h999 +a0.1 -j +r4, tj. byl zapnutý supersampling s mezní hodnotou 0,1 a maximální počet primárních paprsků procházejících pixelem byl roven 4×4=16. Teoreticky by se tedy měla spočítat barva pro 1000×(999+1)×­4×4=16 000 000 paprsků, díky použití adaptivního supersamplingu se jich však použilo „pouze“ 4 117 360 (počet řádků se zvýšil o jedničku právě kvůli adaptivnímu supersamplingu, protože bylo nutné zkontrolovat správně i první řádek pixelů, které již nad sebou nemají žádné sousedy). Došlo tedy ke čtyrnásobnému urychlení výpočtu oproti situaci, kdy by byl použitý neadaptivní supersampling.

povray4513

Obrázek 13: Obrázek o rozlišení 1000×999 pixelů vykreslený s volbami +w1000 +h999 +a0.1 -j +r4

7. Adaptivní rekurzivní supersampling

Adaptivní rekurzivní supersampling vznikl dalším vylepšením supersamplingu nerekurzivního. Zatímco u výše popsané metody supersamplingu došlo na základě barevné odlišnosti dvou sousedních pixelů k vyslání buď jednoho nebo naopak maximálního nastaveného množství primárních paprsků jedním pixelem (například jeden vs. šestnáct paprsků), je rekurzivní supersampling rozšířen takovým způsobem, že dochází k postupnému dělení pixelů na subpixely, přičemž pro každý subpixel je rozhodnuto, zda je již jeho dělení u konce nebo zda má dojít k jeho dalšímu rekurzivnímu rozdělení. Princip je naznačen na čtrnáctém obrázku. Nejprve jsou všemi čtyřmi rohy pixelu vyslány čtyři primární světelné paprsky. V případě, že je rozdíl v jejich barvách menší než prahová hodnota, dojde k vykreslení pixelu bez dalšího dělení.

povray4514

Obrázek 14: Princip adaptivního rekurzivního supersamplingu.

V opačném případě dojde k rozdělení pixelu na čtyři subpixely. Do rohů těchto subpixelů jsou opět vyslány primární paprsky (některé paprsky není zapotřebí generovat, protože jejich barvy jsou známé z předchozího kroku). U těch subpixelů, kde je rozdíl barev malý (levý horní roh na obrázku číslo 14) již k dalšímu dělení nedochází, u všech tří dalších subpixelů ano. Postupně je tedy dělení prováděno v oblasti mezi dvěma různobarevnými plochami až do maximální nastavené hloubky. Tato metoda dokáže vykreslit scénu ve stejné kvalitě jako metoda předchozí, ovšem mnohdy s méně primárními paprsky vyslanými do scény. Na druhou stranu pro některé pixely může nastat situace, kdy se počet generovaných primárních paprsků rapidně zvyšuje – jedná se o oblasti s velmi jemným vzorkem, jehož velikost je například o dva řády menší než velikost pixelu.

povray4515

Obrázek 15: Scéna vykreslená pomocí adaptivního rekurzivního supersamplingu. Porovnejte s obrázkem číslo 12 (názory na to, který výsledek je vizuálně kvalitnější, se liší).

UX DAy - tip 2

8. Obsah další části seriálu

V následující části seriálu o raytraceru POV-Ray si vysvětlíme další metodu používanou pro odstranění aliasu. Jedná se o takzvaný jittering (roztřesení) používaný společně se supersamplingem. Zajímavé je, že i v lidském oku dochází díky uspořádání světlocitlivých a barvocitlivých buněk k velmi dokonalému jitteringu, proto je lidský zrak vůči aliasu do značné míry imunní (pokud by nebyl, nešlo by například sledovat televizi či monitor). Také si ukážeme, jak lze alias odstranit při tvorbě animací a také jak je možné – poněkud překvapivě – alias dokonce využít k tvorbě některých zajímavých procedurálních textur.

povray4516

Obrázek 16: Procedurální textura zadaná vlastní matematickou funkcí, u níž se využívá aliasu. Zde tedy alias plní užitečnou úlohu, na rozdíl od předchozích scén se šachovnicovou podlahou.

Byl pro vás článek přínosný?

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.