Obsah
1. Modulace normálových vektorů – bump mapping
2. Princip bump mappingu
3. Použití procedurálních textur při bump mappingu
4. První příklad – procedurální textura „crackle“ jako zdroj pro bump mapping
5. Druhý příklad – procedurální textura „granite“ jako zdroj pro bump mapping
6. Třetí příklad – změna hodnoty turbulence pro procedurální texturu „marble“
7. Čtvrtý příklad – změna hodnoty turbulence pro procedurální texturu „bumps“
8. Obsah další části seriálu
1. Modulace normálových vektorů – bump mapping
Ve třinácté a především pak čtrnácté části tohoto seriálu byly vysvětleny principy Phongova osvětlovacího modelu, který představuje základ pro výpočet osvětlení všech potenciálně viditelných bodů na povrchu těles. Phongův osvětlovací model je mimo vlastní POV-Ray použitý i v mnoha dalších aplikacích zaměřených na vykreslování trojrozměrných scén, protože výpočty světelných poměrů jsou poměrně rychlé a výsledná scéna současně působí přirozeně. Výsledek snah o co nejrychlejší a přesto kvalitní obrázky trojrozměrných scén samozřejmě vyústil v kompromisní model, který se však s úspěchem používá již několik desetiletí, i když je nutné říci, že se vlastně jedná o ad-hoc řešení, které pouze přibližně simuluje skutečné světelné poměry na povrchu těles a některé optické jevy se s jeho využitím nedají přímo vytvořit (například „prasátka“, které jsou v POV-Rayi simulovány pomocí odlišné metody).
Obrázek 1: Vodní hladina byla v této scéně vytvořena pomocí modulace normál, ve skutečnosti se však jedná o geometricky zcela rovnou plochu
Osvětlovací model je při vykreslování využit ve chvíli, kdy světelný paprsek dopadne na povrch tělesa, od nějž se následně odrazí (popř. i zlomí směrem dovnitř tělesa, ovšem pouze u těles alespoň částečně průhledných), ale vždy s určitým rozptylem – světlo je tedy teoreticky vyzářeno do všech směrů. Míru vyzáření světla lze vyjádřit funkcí, jejíž výsledek závisí na směru dopadajícího světelného paprsku (vzájemné pozici světelného zdroje a povrchu tělesa), intenzitě a barvě světla (barva světla souvisí s jeho vlnovou délkou), normálovém vektoru v místě dopadu paprsku na povrch objektu atd. Právě orientace normálového vektoru, tj. vektoru, jenž je kolmý na povrch tělesa v místě dopadu paprsku, má velký vliv na výslednou barvu dané části tělesa. I malá změna orientace tohoto vektoru (který pak již vlastně nelze nazývat normálový) může vést ke značné vizuální změně na zobrazeném povrchu. Cílená změna orientace normálových vektorů se nazývá modulace normálových vektorů a v počítačové grafice se pro ni vžil pojem bump mapping, tedy tvorba „hrbolků“.
Obrázek 2: I tato vodní hladina byla vytvořena s využitím modulace normálových vektorů
2. Princip bump mappingu
Princip práce bump mappingu je poměrně jednoduchý – ve své podstatě se jedná o rozšíření texturování. Ve chvíli, kdy světelný paprsek dopadne na povrch tělesa, jsou na základě místa dopadu (jedná se o bod ležící v prostoru) vypočteny souřadnice v textuře (podle typu textury se jedná o bod ležící v ploše či prostoru), orientace normálového vektoru a popř. také souřadnice do další textury, která je použita právě při bump mappingu. Na základě hodnoty získané z této textury je načtena hodnota z tabulky nazvané slope_map, ze které se získá informace, jakým způsobem má být změněna orientace normálového vektoru. Normálový vektor je skutečně na základě této informace modifikován (a to velmi jednoduše – k jeho koncovému bodu se přičte hodnota načtená z tabulky slope_map) a následně znovu normalizován. Posléze se již tato nová hodnota normálového vektoru použije při výpočtu osvětlení, který je založen, jak jsme si již řekli ve čtrnácté části tohoto seriálu, na následující rovnici:
I=caIa+cdId(NL)+csIs(VR)n
Ve výsledku tento proces vede k tvorbě zdánlivě hrbolatých povrchů, i když se geometrie zobrazovaného tělesa ve skutečnosti nijak nezmění – to bude v demonstračních příkladech patrné při pohledu na hranici mezi tělesem a jeho pozadím, která má původní tvar, i když by (v případě skutečné změny tvaru povrchu) měla kopírovat vystínované hrbolky.
Obrázek 3: Klasická scéna ve světě raytracingu – několik reflexních koulí z nichž prostřední má při výpočtu osvětlení modulované normálové vektory svého povrchu
3. Použití procedurálních textur při bump mappingu
Prakticky každý vyspělejší raytracer obsahuje speciální typy procedurálních textur, které jsou určené pro bump mapping (viz historické obrázky 3 a 4). Tak tomu bylo i v případě POV-Raye, který ve verzi 1 i 2 obsahoval například specializovanou texturu nazvanou příznačně bumps nebo dents. Ve třetí verzi však došlo k dlouho očekávanému sloučení procedurálních textur určených pro modulaci normálových vektorů i „normálních“ procedurálních textur určených pro změnu barvy těles, takže nyní je možné pro bump mapping použít prakticky jakoukoli procedurální texturu – my jsme s popisem těchto textur začali v patnácté části tohoto seriálu. V následujících čtyřech demonstračních příkladech budou pro modulaci normálových vektorů použity procedurální textury crackle, granite, marble a bumps. Ve všech příkladech budou použity hodnoty z implicitní tabulky slope_map, způsob její změny si vysvětlíme příště.
Obrázek 4: Tatáž scéna, jaká byla zobrazena na třetím obrázku (jen viděná z jiného místa) vykreslená v dávné minulosti v odlišném raytraceru Rayshade (pro POV-Ray bylo nutné původní zdrojový kód scény celý přepsat)
4. První příklad – procedurální textura „crackle“ jako zdroj pro bump mapping
V dnešním prvním demonstračním příkladu je ukázáno, jakým způsobem je možné specifikovat procedurální texturu určenou pro bump mapping spolu s některými jejími základními parametry. V demonstrační scéně je na podkladové rovině umístěno jediné těleso – zelená koule –, na jejímž povrchu dochází při výpočtu světelných podmínek k modulaci normálových vektorů. Jako procedurální textura pro modulaci byla zvolena již dříve popsaná textura crackle, jež tvoří typický vzorek připomínající suchou půdu. Ze zdrojového kódu příkladu je patrné, že do definice textury (texture) byl, kromě již známých poduzlů pigment a finish, přidán nový poduzel nazvaný normal, který obsahuje jak jméno použité procedurální textury, tak i parametr bump_size (míra výšky vytvářených hrbolků) a parametr scale (změna velikosti hrbolků). Následuje výpis zdrojového kódu tohoto demonstračního příkladu:
// ------------------------------------------------------------
// První demonstrační příklad na bump mapping.
//
// Jednoduchá scéna s jedním uzavřeným objektem, jedním nekonečným
// objektem, dvojicí světel a jednou kamerou (pozorovatelem).
//
// Normálové vektory objektu (koule) jsou modulovány - bump mapping.
//
// Založeno na souboru původně vytvořeného Danem Farmerem (leden 2002)
//
// rendering lze spustit příkazem: povray +W1024 +H768 +B100 +FN +D +Iscena.pov +Oscena.png
// (pro náhled postačí zadat povray scena.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" // zde je textura pro podkladovou rovinu
// nastavení kamery (pozorovatele)
camera {
location <1.65, 5.5, -5.0> // pozice kamery
up <0.0, 1.0, 0.0> // vektor směřující vzhůru
right <4/3, 0.0, 0.0> // vektor směřující doprava
look_at <0, 0.5, -1.0> // bod, na který kamera směřuje
}
// dva světelné zdroje
light_source {
< 21, 12, -20> // pozice světelného zdroje
color White // barva světla (plná bílá)
}
light_source {
< 32, 11, -20> // pozice světelného zdroje
color LightGray // barva světla
}
// jediný uzavřený objekt ve scéně - zelená koule
sphere {
<0, 0, 0>, // souřadnice středu koule
1.75 // poloměr koule
texture { // textura - povrch koule
pigment {
color green 0.90 // barva povrchu
}
normal { // modulace normálových vektorů
crackle // typ procedurální textury
bump_size 1.5 // relativní velikost zvlnění
scale 0.4 // změna měřítka (hustoty zvlnění povrchu)
}
finish { // optické vlastnosti materiálu
phong 1 // velikost a síla odlesků
phong_size 100
}
}
}
// druhý objekt - nekonečná rovina
plane {
y, // orientace roviny
-1.5 // vzdálenost od počátku
texture { // textura - vlastnosti povrchu
T_Stone1 // definováno v externím souboru
pigment { // vlastní vzorek textury
octaves 3 // modifikace procedurálního vzorku
rotate 90*z
}
finish { // optické vlastnosti materiálu
reflection 0.10
}
}
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Obrázek 5: Výsledek běhu prvního demonstračního příkladu
5. Druhý příklad – procedurální textura „granite“ jako zdroj pro bump mapping
Ve druhém demonstračním příkladu je, možná poněkud netradičně, pro bump mapu použita procedurální textura granite. Tato textura sice při běžném použití vypadá velmi náhodně, což nepřímo značí její nevhodnost pro modulaci normálových vektorů, ovšem při větším zvětšení tato náhodnost do značné míry zmizí a výsledná bump mapa je v mnoha případech velmi dobře použitelná, například při vytváření plechových předmětů, artefaktů vyrobených z roztepaného zlata apod. Druhý demonstrační příklad má tvar:
// ------------------------------------------------------------
// Druhý demonstrační příklad na bump mapping.
//
// Jednoduchá scéna s jedním uzavřeným objektem, jedním nekonečným
// objektem, dvojicí světel a jednou kamerou (pozorovatelem).
//
// Normálové vektory objektu (koule) jsou modulovány - bump mapping.
//
// Založeno na souboru původně vytvořeného Danem Farmerem (leden 2002)
//
// rendering lze spustit příkazem: povray +W1024 +H768 +B100 +FN +D +Iscena.pov +Oscena.png
// (pro náhled postačí zadat povray scena.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" // zde je textura pro podkladovou rovinu
// nastavení kamery (pozorovatele)
camera {
location <1.65, 5.5, -5.0> // pozice kamery
up <0.0, 1.0, 0.0> // vektor směřující vzhůru
right <4/3, 0.0, 0.0> // vektor směřující doprava
look_at <0, 0.5, -1.0> // bod, na který kamera směřuje
}
// dva světelné zdroje
light_source {
< 21, 12, -20> // pozice světelného zdroje
color White // barva světla (plná bílá)
}
light_source {
< 32, 11, -20> // pozice světelného zdroje
color LightGray // barva světla
}
// jediný uzavřený objekt ve scéně - červená koule
sphere {
<0, 0, 0>, // souřadnice středu koule
1.75 // poloměr koule
texture { // textura - povrch koule
pigment {
color red 0.90 // barva povrchu
}
normal { // modulace normálových vektorů
granite
bump_size 1.2 // relativní velikost zvlnění
scale 8.4 // změna měřítka (hustoty zvlnění povrchu)
}
finish { // optické vlastnosti materiálu
phong 1 // velikost a síla odlesků
phong_size 100
}
}
}
// druhý objekt - nekonečná rovina
plane {
y, // orientace roviny
-1.5 // vzdálenost od počátku
texture { // textura - vlastnosti povrchu
T_Stone1 // definováno v externím souboru
pigment { // vlastní vzorek textury
octaves 3 // modifikace procedurálního vzorku
rotate 90*z
}
finish { // optické vlastnosti materiálu
reflection 0.10
}
}
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Obrázek 6: Výsledek běhu druhého demonstračního příkladu
6. Třetí příklad – změna hodnoty turbulence pro procedurální texturu „marble“
Ve třetím demonstračním příkladu je ukázán vliv míry turbulence na tvar bump mapy použité při modulaci normálových vektorů. V modelované scéně se nachází devět naprosto stejných koulí s lesklým jednobarevným povrchem modulovaným pomocí procedurální textury marble. Pokud není tato textura modifikována turbulencí, je výsledkem těleso, na němž jsou vytvořeny pravidelné pásky tvořící reliéf. Kdyby se jednalo o skutečný plastický reliéf, měl by v řezu pilovitý průběh, ovšem bump mapa, jak již víme z předchozích odstavců, ve skutečnosti povrch tělesa nemění. Spolu se zvětšující se mírou turbulence přestává být pravidelný reliéf patrný a naopak se ukazuje struktura vzdáleně připomínající omítku. Výpis třetího demonstračního příkladu má tvar:
// ------------------------------------------------------------
// Třetí demonstrační příklad ukazující práci s procedurálními
// texturami použitými jako zdroj pro modulaci normál.
//
// Postupná změna hodnoty turbulence pro zvolenou procedurální
// texturu marble od hodnoty 0.0 do hodnoty 0.8.
//
// rendering lze spustit příkazem:
// povray +W1024 +H1024 +B100 +FN +D +Itextures.pov +Otextures.png
//
// !POZOR: scénu je nutné vykreslit se stejným horizontálním
// i vertikálním rozlišením!
// ------------------------------------------------------------
#version 3.0
global_settings {
assumed_gamma 2.2
}
#include "colors.inc"
camera { // nastavení kamery
orthographic // bez perspektivy
location < 0, 0, -2.1> // pozice kamery
right 15*x // šířka a výška snímané části scény
up 15*y
direction z // směr pohledu kamery (k počátku)
}
light_source { // světelný zdroj
<200, 200, -500> // pozice
color White // barva
}
#declare COL1=-4.5; // posuny objektů ve vztahu
#declare COL2= 0.0; // k pomyslné mřížce
#declare COL3= 4.5; // o rozměrech 3x3
#declare ROW1= 4.5;
#declare ROW2= 0.0;
#declare ROW3=-4.5;
#declare Z=0.0;
#declare NORMAL=normal { // testovací procedurální textura
marble // základ pro tvorbu textury mramoru
bump_size 1.5
}
#declare OBJECT=sphere {
<0,0,0>, 2
}
object {
OBJECT
texture {
pigment {
color Cyan
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.0
}
}
translate <COL1, ROW1, Z>
}
object {
OBJECT
texture {
pigment {
color Cyan
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.1
}
}
translate <COL2, ROW1, Z>
}
object {
OBJECT
texture {
pigment {
color Cyan
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.2
}
}
translate <COL3, ROW1, Z>
}
object {
OBJECT
texture {
pigment {
color Cyan
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.3
}
}
translate <COL1, ROW2, Z>
}
object {
OBJECT
texture {
pigment {
color Cyan
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.4
}
}
translate <COL2, ROW2, Z>
}
object {
OBJECT
texture {
pigment {
color Cyan
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.5
}
}
translate <COL3, ROW2, Z>
}
object {
OBJECT
texture {
pigment {
color Cyan
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.6
}
}
translate <COL1, ROW3, Z>
}
object {
OBJECT
texture {
pigment {
color Cyan
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.7
}
}
translate <COL2, ROW3, Z>
}
object {
OBJECT
texture {
pigment {
color Cyan
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.8
}
}
translate <COL3, ROW3, Z>
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Obrázek 7: Výsledek běhu třetího demonstračního příkladu
7. Čtvrtý příklad – změna hodnoty turbulence pro procedurální texturu „bumps“
Ve čtvrtém demonstračním příkladu je ukázáno použití snad nejtypičtější procedurální textury využívané při modulaci normálových vektorů. Jedná se o texturu bumps. I na tuto procedurální texturu je samozřejmě možné aplikovat turbulenci a měnit tak náhodnost hrbolků opticky vytvořených na povrchu vykreslovaného tělesa. V příkladu je míra turbulence měněna od hodnoty 0,0 (žádná turbulence, používá se nemodifikovaný vzorek generovaný procedurální texturou) až po hodnotu 0,8 (poměrně vysoká míra turbulence a tím také náhodnosti hrbolků). Textura bumps má při modulaci normálových vektorů široké možnosti použití, od tvorby omítek (malá měřítka) přes kamenné povrchy až po zprohýbané plechy či listy.
// ------------------------------------------------------------
// Čtvrtý demonstrační příklad ukazující práci s procedurálními
// texturami použitými jako zdroj pro modulaci normál.
//
// Postupná změna hodnoty turbulence pro zvolenou procedurální
// texturu bumps od hodnoty 0.0 do hodnoty 0.8.
//
// rendering lze spustit příkazem:
// povray +W1024 +H1024 +B100 +FN +D +Itextures.pov +Otextures.png
//
// !POZOR: scénu je nutné vykreslit se stejným horizontálním
// i vertikálním rozlišením!
// ------------------------------------------------------------
#version 3.0
global_settings {
assumed_gamma 2.2
}
#include "colors.inc"
camera { // nastavení kamery
orthographic // bez perspektivy
location < 0, 0, -2.1> // pozice kamery
right 15*x // šířka a výška snímané části scény
up 15*y
direction z // směr pohledu kamery (k počátku)
}
light_source { // světelný zdroj
<0, 0, -500> // pozice
color White // barva
}
#declare COL1=-4.5; // posuny objektů ve vztahu
#declare COL2= 0.0; // k pomyslné mřížce
#declare COL3= 4.5; // o rozměrech 3x3
#declare ROW1= 4.5;
#declare ROW2= 0.0;
#declare ROW3=-4.5;
#declare Z=0.0;
#declare NORMAL=normal { // testovací procedurální textura
bumps // základ pro tvorbu textury mramoru
bump_size 1.5
scale 0.7
}
#declare OBJECT=sphere {
<0,0,0>, 2
}
object {
OBJECT
texture {
pigment {
color Yellow
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.0
}
}
translate <COL1, ROW1, Z>
}
object {
OBJECT
texture {
pigment {
color Yellow
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.1
}
}
translate <COL2, ROW1, Z>
}
object {
OBJECT
texture {
pigment {
color Yellow
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.2
}
}
translate <COL3, ROW1, Z>
}
object {
OBJECT
texture {
pigment {
color Yellow
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.3
}
}
translate <COL1, ROW2, Z>
}
object {
OBJECT
texture {
pigment {
color Yellow
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.4
}
}
translate <COL2, ROW2, Z>
}
object {
OBJECT
texture {
pigment {
color Yellow
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.5
}
}
translate <COL3, ROW2, Z>
}
object {
OBJECT
texture {
pigment {
color Yellow
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.6
}
}
translate <COL1, ROW3, Z>
}
object {
OBJECT
texture {
pigment {
color Yellow
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.7
}
}
translate <COL2, ROW3, Z>
}
object {
OBJECT
texture {
pigment {
color Yellow
}
finish {
phong 1
}
normal {
NORMAL
turbulence 0.8
}
}
translate <COL3, ROW3, Z>
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Obrázek 8: Výsledek běhu čtvrtého demonstračního příkladu
8. Obsah další části seriálu
V následující části seriálu o aplikaci POV-Ray se (po dokončení vysvětlení modulace normálových vektorů) budeme zabývat nastavením dalších optických vlastností materiálů těles využívaných především při výpočtu průhlednosti, lomu světelných paprsků na povrchu těles a v neposlední řadě také simulaci rozkladu světla při průchodu průhlednými tělesy, s čímž souvisí i simulace vzniku světelných „prasátek“. Uvidíme, že POV-Ray dokáže provádět nejenom klasické zpětné sledování paprsku, tak jako všechny ostatní raytracery, ale také výpočetně mnohem náročnější dopředné sledování paprsku, které se využívá právě při modelování složitějších optických jevů vznikajících na povrchu či uvnitř těles. Jeden takový – běžnými raytracery neprodukovatelný – optický jev je ukázán i na dnešním posledním obrázku:
Obrázek 9: Ukázka lomu a částečného rozkladu světelných paprsků na rozhraní dvou různých materiálů