Obsah
1. Dokončení předchozí části: Phongův osvětlovací model prakticky
2. První demonstrační příklad: změna ambientní a difúzní složky Phongova osvětlovacího modelu
3. Druhý demonstrační příklad: změna koeficientu odlesků Phongova osvětlovacího modelu
4. Nanášení textur na povrch těles
5. Procedurální textury v POV-Rayi
6. Obsah další části seriálu
1. Dokončení předchozí části: Phongův osvětlovací model prakticky
V předchozí části tohoto seriálu jsme si popsali Phongův osvětlovací model. Stručně řečeno lze říci, že intenzita světla odraženého od povrchu předmětu je vypočtena na základě tří složek. První složkou je všesměrové (ambientní) světlo, které přichází ze všech stran a odráží se také do všech stran. Druhou složkou je difúzní světlo, jehož intenzita závisí na vzájemné poloze povrchu tělesa a světelného zdroje – čím kolměji světelný zdroj osvětluje plochu, tím je intenzita difúzní části světla větší. Poslední složkou je odražené (specular) světlo, jehož intenzita závisí na odchylce odraženého paprsku od vektoru směřujícího k pozorovateli – intenzita tohoto světla je nejvyšší v případě, že se paprsek jdoucí ze světelného zdroje odrazí přímo k pozorovateli (tento fenomén samozřejmě známe i z reálného světa, viz „prasátka“ odražená například od vzdáleného zavírajícího se okna). V POV-Rayi je možné všechny tři složky (resp. jejich koeficienty) zapsat pomocí uzlu finish:
// uzel, pomocí něhož se specifikují parametry Phongova osvětlovacího modelu
finish {
ambient barva_ambientního_světla // většinou zapsáno formou třísložkového vektoru
diffuse koeficient 0-1 // odpovídá 0% až 100% difúzní složky
phong koeficient 0-1 // odpovídá 0% až 100% odrazivé složky
phong_size koeficient >=0 // odpovídá mocnině n
}
2. První demonstrační příklad: změna ambientní a difúzní složky Phongova osvětlovacího modelu
V dnešním prvním demonstračním příkladu je ukázán způsob změny ambientní a současně i difúzní složky při specifikaci optických parametrů povrchů těles za pomoci Phongova osvětlovacího modelu. Ve scéně je vytvořeno celkem 5×5 geometricky zcela totožných těles osvětlených bílým světlem (konkrétně se jedná o bodový světelný zdroj), které jsou zobrazeny s využitím ortogonálního mapování (bez zkreslení vlivem perspektivy). Ve vodorovném směru se na povrchu těchto těles mění difúzní složka, ve směru svislém pak složka ambientní. Ambientní složka se mění od hodnoty <0, 0, 0>, tj. absolutně černé barvy až po hodnotu <1, 1, 1>, tj. bílou barvu. Difúzní složka nabývá hodnot od 0,0 (0%) do 1,0 (100%). Globální hodnota ambientního (všesměrového) osvětlení je nastavena na šedou barvu, protože se tato hodnota vždy násobí ambientní složkou platnou pro daný povrch. Zdrojový kód prvního demonstračního příkladu vypadá následovně:
// ------------------------------------------------------------
// První demonstrační příklad na využití Phongova osvětlovacího
// modelu.
//
// Změna ambientní a difúzní složky.
//
// rendering lze spustit příkazem:
// povray +W800 +H600 +B100 +FN +D +Iphong.pov +Ophong.png
// (pro náhled postačí zadat povray phong.pov)
// ------------------------------------------------------------
global_settings {
assumed_gamma 2.2
ambient_light <0.5, 0.5, 0.5> // ambientní složka materiálu se násobí touto konstantou
}
camera {
orthographic // vypnutí perspektivního zkreslení
location <0, 0, -10> // umístění kamery
right 4/3 * x * 20 // vektor směřující doprava
up y * 20 // a nahoru
look_at <0, 0, 0> // bod, na který se kamera zaměřila
}
light_source { // první světelný zdroj
<50, 50, -100> // pozice světelného zdroje
color red 1.0 green 1.0 blue 1.0 // barva světelného zdroje
}
light_source { // druhý světelný zdroj
<0, 0, -10000> // pozice světelného zdroje
color red 0.2 green 0.2 blue 0.2 // barva světelného zdroje
shadowless
}
plane { // rovina tvořící pozadí scény
<0, 0, 1>, 3 // posun a orientace roviny
hollow on
pigment { // procedurální textura
agate
agate_turb 0.3
}
finish { // optické vlastnosti materiálu povrchu
ambient 0.1
diffuse 0.4
}
}
// pozice jednotlivých objektů ve scéně
#declare Row1 = +8;
#declare Row2 = +4;
#declare Row3 = 0;
#declare Row4 = -4;
#declare Row5 = -8;
#declare Col1 = -10;
#declare Col2 = -5;
#declare Col3 = 0;
#declare Col4 = +5;
#declare Col5 = +10;
// textura
#declare Tex =
texture {
pigment {
color red 1 green 0 blue 0
}
}
// následují jednotlivé objekty
sphere { <Col1, Row1, 0> 1.5 texture { Tex } finish {ambient <0.00, 0.00, 0.00> diffuse 0.00} }
sphere { <Col2, Row1, 0> 1.5 texture { Tex } finish {ambient <0.00, 0.00, 0.00> diffuse 0.25} }
sphere { <Col3, Row1, 0> 1.5 texture { Tex } finish {ambient <0.00, 0.00, 0.00> diffuse 0.50} }
sphere { <Col4, Row1, 0> 1.5 texture { Tex } finish {ambient <0.00, 0.00, 0.00> diffuse 0.75} }
sphere { <Col5, Row1, 0> 1.5 texture { Tex } finish {ambient <0.00, 0.00, 0.00> diffuse 1.00} }
sphere { <Col1, Row2, 0> 1.5 texture { Tex } finish {ambient <0.25, 0.25, 0.25> diffuse 0.00} }
sphere { <Col2, Row2, 0> 1.5 texture { Tex } finish {ambient <0.25, 0.25, 0.25> diffuse 0.25} }
sphere { <Col3, Row2, 0> 1.5 texture { Tex } finish {ambient <0.25, 0.25, 0.25> diffuse 0.50} }
sphere { <Col4, Row2, 0> 1.5 texture { Tex } finish {ambient <0.25, 0.25, 0.25> diffuse 0.75} }
sphere { <Col5, Row2, 0> 1.5 texture { Tex } finish {ambient <0.25, 0.25, 0.25> diffuse 1.00} }
sphere { <Col1, Row3, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.00} }
sphere { <Col2, Row3, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.25} }
sphere { <Col3, Row3, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50} }
sphere { <Col4, Row3, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.75} }
sphere { <Col5, Row3, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 1.00} }
sphere { <Col1, Row4, 0> 1.5 texture { Tex } finish {ambient <0.75, 0.75, 0.75> diffuse 0.00} }
sphere { <Col2, Row4, 0> 1.5 texture { Tex } finish {ambient <0.75, 0.75, 0.75> diffuse 0.25} }
sphere { <Col3, Row4, 0> 1.5 texture { Tex } finish {ambient <0.75, 0.75, 0.75> diffuse 0.50} }
sphere { <Col4, Row4, 0> 1.5 texture { Tex } finish {ambient <0.75, 0.75, 0.75> diffuse 0.75} }
sphere { <Col5, Row4, 0> 1.5 texture { Tex } finish {ambient <0.75, 0.75, 0.75> diffuse 1.00} }
sphere { <Col1, Row5, 0> 1.5 texture { Tex } finish {ambient <1.00, 1.00, 1.00> diffuse 0.00} }
sphere { <Col2, Row5, 0> 1.5 texture { Tex } finish {ambient <1.00, 1.00, 1.00> diffuse 0.25} }
sphere { <Col3, Row5, 0> 1.5 texture { Tex } finish {ambient <1.00, 1.00, 1.00> diffuse 0.50} }
sphere { <Col4, Row5, 0> 1.5 texture { Tex } finish {ambient <1.00, 1.00, 1.00> diffuse 0.75} }
sphere { <Col5, Row5, 0> 1.5 texture { Tex } finish {ambient <1.00, 1.00, 1.00> diffuse 1.00} }
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
První demonstrační příklad po vykreslení v POV-Rayi
3. Druhý demonstrační příklad: změna koeficientu odlesků Phongova osvětlovacího modelu
Ve druhém demonstračním příkladu zůstává ambientní i difúzní složka světla pro všechny objekty konstantní, mění se však intenzita odlesků (ve vodorovném směru). Ve směru svislém se postupně zvyšuje mocnina n, která určuje jak velikost „prasátka“, tak i rychlost změny intenzity světla od jeho středu směrem k okraji. Čím je hodnota n vyšší, tím menší, ale zato kontrastnější „prasátko“ se vytvoří. Zdrojový kód tohoto příkladu má tvar:
// ------------------------------------------------------------
// Druhý demonstrační příklad na využití Phongova osvětlovacího
// modelu.
//
// Změna odlesků.
//
// rendering lze spustit příkazem:
// povray +W800 +H600 +B100 +FN +D +Iphong.pov +Ophong.png
// (pro náhled postačí zadat povray phong.pov)
// ------------------------------------------------------------
global_settings {
assumed_gamma 2.2
ambient_light <0.5, 0.5, 0.5> // ambientní složka materiálu se násobí touto konstantou
}
camera {
orthographic // vypnutí perspektivního zkreslení
location <0, 0, -10> // umístění kamery
right 4/3 * x * 20 // vektor směřující doprava
up y * 20 // a nahoru
look_at <0, 0, 0> // bod, na který se kamera zaměřila
}
light_source { // první světelný zdroj
<50, 50, -100> // pozice světelného zdroje
color red 1.0 green 1.0 blue 1.0 // barva světelného zdroje
}
light_source { // druhý světelný zdroj
<0, 0, -10000> // pozice světelného zdroje
color red 0.2 green 0.2 blue 0.2 // barva světelného zdroje
shadowless
}
plane { // rovina tvořící pozadí scény
<0, 0, 1>, 3 // posun a orientace roviny
hollow on
pigment { // procedurální textura
agate
agate_turb 0.3
}
finish { // optické vlastnosti materiálu povrchu
ambient 0.1
diffuse 0.4
}
}
// pozice jednotlivých objektů ve scéně
#declare Row1 = +8;
#declare Row2 = +4;
#declare Row3 = 0;
#declare Row4 = -4;
#declare Row5 = -8;
#declare Col1 = -10;
#declare Col2 = -5;
#declare Col3 = 0;
#declare Col4 = +5;
#declare Col5 = +10;
// textura
#declare Tex =
texture {
pigment {
color red 1 green 0 blue 0
}
}
// následují jednotlivé objekty
sphere { <Col1, Row1, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.00 phong_size 1} }
sphere { <Col2, Row1, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.25 phong_size 1} }
sphere { <Col3, Row1, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.50 phong_size 1} }
sphere { <Col4, Row1, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.75 phong_size 1} }
sphere { <Col5, Row1, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 1.00 phong_size 1} }
sphere { <Col1, Row2, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.00 phong_size 5} }
sphere { <Col2, Row2, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.25 phong_size 5} }
sphere { <Col3, Row2, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.50 phong_size 5} }
sphere { <Col4, Row2, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.75 phong_size 5} }
sphere { <Col5, Row2, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 1.00 phong_size 5} }
sphere { <Col1, Row3, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.00 phong_size 10} }
sphere { <Col2, Row3, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.25 phong_size 10} }
sphere { <Col3, Row3, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.50 phong_size 10} }
sphere { <Col4, Row3, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.75 phong_size 10} }
sphere { <Col5, Row3, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 1.00 phong_size 10} }
sphere { <Col1, Row4, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.00 phong_size 20} }
sphere { <Col2, Row4, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.25 phong_size 20} }
sphere { <Col3, Row4, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.50 phong_size 20} }
sphere { <Col4, Row4, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.75 phong_size 20} }
sphere { <Col5, Row4, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 1.00 phong_size 20} }
sphere { <Col1, Row5, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.00 phong_size 50} }
sphere { <Col2, Row5, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.25 phong_size 50} }
sphere { <Col3, Row5, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.50 phong_size 50} }
sphere { <Col4, Row5, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 0.75 phong_size 50} }
sphere { <Col5, Row5, 0> 1.5 texture { Tex } finish {ambient <0.50, 0.50, 0.50> diffuse 0.50 phong 1.00 phong_size 50} }
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Druhý demonstrační příklad po vykreslení v POV-Rayi
4. Nanášení textur na povrch těles
V POV-Rayi je možné popsat vizuální vlastnosti povrchu modelovaných těles několika různými způsoby, popř. i jejich kombinacemi. Nejjednodušší je specifikace konstantní barvy materiálu, ze kterého je těleso složeno. Tímto způsobem, se kterým jsme se už setkali prakticky ve všech demonstračních příkladech, však lze vytvářet pouze ty nejjednodušší scény. Jednobarevná tělesa se často používají u technických modelů (strojnictví, stavitelství, technický design), u kterých je větší důraz kladen na geometrii těles (jejich tvar) a ne na fotorealističnost výsledné scény. To je ostatně patrné i z prvního obrázku, jehož předlohu jsme si ukázali v předchozích částech tohoto seriálu.
Scéna, u níž je dbáno především na tvar jednotlivých součástek a ne na fotorealističnost výsledku
Další možností je nanesení dvojrozměrné textury na povrch tělesa. Dvojrozměrná textura může být uložena v externím souboru jako běžný rastrový obrázek, což je pro mnoho aplikací výhodné – je například možné do pozadí vykreslované scény vložit fotografii nebo některé tvarově složité objekty nahradit pouhým obdélníkem s nanesenou texturou (s některými průhlednými pixely) – tato technika, který bývá v různých obměnách použita i u počítačových her, se nazývá billboarding.
Rastrová textura tvořící plochu okna obsahuje průhledné pixely
Ovšem tento typ textur přináší při svém použití i některé nevýhody: velké nároky na kapacitu operační paměti, především při použití velkých rastrových obrázků, vznik aliasu, který v tomto případě není možné zcela potlačit (zejména u animací, tj. tvorbě snímků, které se od sebe liší pouze v malých detailech) a v neposlední řadě také to, že 2D obrázek, tj. původně obdélník, je při nanesení na obecný povrch tělesa nutně zborcený. V každém případě se těmto typům textur budeme do všech podrobností věnovat v navazujících částech tohoto seriálu.
Scéna, ve které jsou použity textury uložené v rastrových obrázcích
5. Procedurální textury v POV-Rayi
V POV-Rai existuje ještě jeden způsob, jakým je možné povrch těles pokrýt texturou. Jedná se o velmi dobře propracovanou technologii takzvaných procedurálních textur. Tyto textury nejsou reprezentovány rastrovým obrázkem, ale matematickým výrazem, který každému bodu ležícímu v trojrozměrném prostoru přiřazuje jeho barvu, tj. jedná se o funkci color=f(x,y,z). Vzhledem k tomu, že má funkce definiční obor R3, nedochází většinou (výjimky se najdou) při použití procedurálních textur k nežádoucímu aliasu a nároky na kapacitu operační paměti jsou také mnohem menší, protože procedurální textura se vlastně nevytváří dopředu (není uložena ani v operační paměti, ani v externím souboru), jelikož se barva jednotlivých bodů na povrchu těles počítá až při vlastním renderingu. Tato vlastnost je s oblibou použita například při vykreslování na renderovacích farmách složených z počítačů bez pevného disku (ušetří se jak přenosová kapacita propojovací sítě, tak i operační paměť jednotlivých výpočetních uzlů v renderovací farmě).
Příklad použití procedurálních textur
Díky tomu, že procedurální textury vyplňují celý trojrozměrný prostor, ze kterého vykreslované těleso v podstatě „vyřezává“ obsazený podprostor, nedochází k žádnému zborcení procedurální textury na povrchu tělesa, i když v mnoha případech je obrazec textury závislý na směru řezu. Jak již bylo napsáno v předchozím odstavci, je procedurální textura specifikována nějakou funkcí. V POV-Rayi lze vhodnou funkci zapsat buď přímo ve formě matematického výrazu nebo se – a to v praxi mnohem častěji – použijí již předdefinované procedurální textury, u nichž lze změnit jejich parametry a barvy (popř. barvové přechody), které jsou v textuře použity. Takový způsob zápisu textury je nejenom velmi úsporný, ale i přenositelný na různé platformy. V minulosti sice existovaly nepatrné rozdíly ve způsobu výpočtu některých procedurálních textur (například u textur používajících generátor náhodných čísel), dnes je však zaručeno – a to i zpětně – že bude procedurální textura vykreslena vždy stejným způsobem.
Procedurální textury dřeva
6. Obsah další části seriálu
V následující části tohoto seriálu si popíšeme další typy procedurálních textur, které je možné v POV-Rayi použít, i způsoby jejich modifikace pomocí různých parametrů. Vzhledem k tomu, že textury nemusí být použity pouze pro vytvoření barevného obrazce na povrchu těles, ale mohou sloužit i pro další činnosti, například modulaci normálových vektorů na stěnách těles (bump mapping), budou příště popsány i tyto zajímavé a v oblasti 3D graficky často používané techniky.
Ukázka bump mappingu (modifikace normálových vektorů na kouli)