Hlavní navigace

POV-Ray a Phongův osvětlovací model

3. 6. 2008
Doba čtení: 13 minut

Sdílet

V dnešní části seriálu o programu POV-Ray si ukážeme použití zbývajících dvou typů světelných zdrojů a dále budou popsány způsoby zadávání optických vlastností materiálů, včetně ovlivnění základních koeficientů Phongova osvětlovacího modelu.

Obsah

1. Plošný zdroj světla
2. První demonstrační příklad – jeden plošný světelný zdroj
3. Druhý demonstrační příklad – více plošných světelných zdrojů
4. Třetí demonstrační příklad – viditelný světelný zdroj
5. Phongův osvětlovací model
6. Výpočet osvětlení s využitím Phongova osvětlovacího modelu
7. Specifikace parametrů Phongova osvětlovacího modelu v POV-Rayi
8. Obsah následující části seriálu

1. Plošný zdroj světla

V předchozí části tohoto seriálu jsme si popsali všesměrové světlo, bodový světelný zdroj a také takzvané reflektorové světlo. V POV-Rayi je však možné simulovat i plošný zdroj světla, který je sice – alespoň co se týká výpočtů – poměrně komplikovaný, zato je s ním možné vytvářet měkké stíny a polostíny. Ve skutečnosti se jedná o pouhé napodobení skutečně plošného světelného zdroje několika zdroji bodovými či reflektorovými, ovšem na výsledném obrázku většinou není tento „podvůdek“ patrný. Bodové světlo je zapsáno opět pomocí uzlu light_source, ovšem kromě specifikace jeho polohy v prostoru a barvy se musí také zadat plocha zdroje (jedná se o dva protilehlé body obdélníka) a počet bodových/reflek­torových světelných zdrojů, kterým se skutečný plošný světelný zdroj nahrazen (tato světla leží v mřížce). Většinou postačuje použít 5×5 bodových světel, u reflektorových ještě méně. Klíčovým slovem adaptive lze povolit adaptivní algoritmus, který redukuje počet vyslaných paprsků ze zdroje světla, čímž se celý výpočet značným způsobem urychlí. Pomocí klíčového slova jitter lze bodová světla náhodně vychýlit ze svých přesných pozic, čímž se zamezí vzniku nežádoucích stínových artefaktů.

2. První demonstrační příklad – jeden plošný světelný zdroj

V dnešním prvním demonstračním příkladu je vzorová scéna osvětlena plošným světelným zdrojem o ploše 1 délkové jednotky2 simulovaným pomocí 5×5=25 bodových světel. Adaptivní algoritmus povolený klíčovým slovem adaptive celý výpočet několikanásobně urychlil. Následuje výpis zdrojového kódu prvního demonstračního příkladu:

 // ------------------------------------------------------------
// První demonstrační příklad na použití světelných zdrojů
// v prostorových scénách vykreslovaných POV-Rayem.
//
// Jeden plošný zdroj světla.
//
// rendering lze spustit příkazem:
//     povray +W800 +H600 +B100 +FN +D +Iscena.pov +Oscena.png
// (pro náhled postačí zadat povray scena.pov)
// ------------------------------------------------------------

#include "colors.inc"
#include "textures.inc"

// nastavení kamery
camera {
    location  <-4, 3, -9>                // pozice kamery
    look_at   <0, 0, 0>                  // bod, na který se kamera dívá
    angle 48                             // zorný úhel
}

// plošný zdroj světla
light_source {
    <2, 6, -3>
    color White
    area_light <1, 0, 0>, <0, 0, 1>, 5, 5
    adaptive 1
    jitter
}



// objekt vytvořený z písmen, jejichž tvary jsou přečteny z externího souboru s fontem
text {
    ttf                                  // formát s uloženým fontem
    "crystal.ttf",                       // soubor s fontem dodávaný současně s POV-Rayem
    "root.cz",                           // text, který se má vytvořit
    0.5,                                 // hloubka textového objektu
    0                                    // mezera mezi znaky
    texture {                            // textura, kterou je objekt pokrytý
        DMFLightOak
        scale 0.5
    }
    scale 2.5                            // změna měřítka textového objektu
    translate <-4, 0, -1>                // posun textového objektu
}



// otexturovaná koule
sphere {
    <0,-1,0>, 1                          // pozice středu a poloměr
    texture {                            // textura, kterou je objekt pokrytý
        Sapphire_Agate
    }
    translate <1.5, 0, -2>               // posun koule ve scéně
}



// kvádr, do kterého je celá scéna uzavřena
box {
    <-12,-2,-12>, <20, 20, 8>
    texture {
        pigment {                        // šachovnicová textura
            checker                      // vyvedená ve stupních šedi
            color rgb<0.1, 0.1, 0.1>
            color rgb<0.5, 0.5, 0.5>
        }
        finish {                         // odlesky a odrazy na povrchu
            diffuse 0.7
            reflection 0.2
        }
    }
}



// ------------------------------------------------------------
// finito
// ------------------------------------------------------------ 
povray1401

Obrázek 1: První demonstrační příklad po vykreslení v POV-Rayi (všimněte si měkkých stínů jak pod textem, tak i pod koulí)

povray1402

Obrázek 2: Pro porovnání – tatáž scéna osvětlená bodovým světlem (rozdíl je patrný také ve stínu uvnitř písmena „z“)

3. Druhý demonstrační příklad – více plošných světelných zdrojů

Druhý demonstrační příklad se uspořádáním objektů podobá příkladu prvnímu, ovšem s tím rozdílem, že je použito více plošných světelných zdrojů, které nejsou složeny ze světel bodových, ale reflektorových. Výpočet je již značně pomalý, proto je také každý plošný zdroj simulován „pouze“ pomocí 3×3 reflektorů:

// ------------------------------------------------------------
// Druhý demonstrační příklad na použití světelných zdrojů
// v prostorových scénách vykreslovaných POV-Rayem.
//
// Několik plošných zdrojů světla.
//
// rendering lze spustit příkazem:
//     povray +W800 +H600 +B100 +FN +D +Iscena.pov +Oscena.png
// (pro náhled postačí zadat povray scena.pov)
// ------------------------------------------------------------

#include "colors.inc"
#include "textures.inc"

// nastavení kamery
camera {
    location  <-4, 3, -9>                // pozice kamery
    look_at   <0, 0, 0>                  // bod, na který se kamera dívá
    angle 48                             // zorný úhel
}

// plošné světelné zdroje simulované pomocí reflektorových světel
light_source {
    <2, 10, -3>
    color      White
    spotlight
    radius     15
    falloff    18
    tightness  10
    area_light <1, 0, 0>, <0, 0, 1>, 3, 3
    adaptive   1
    jitter
    point_at   <0, 0, 0>
}
light_source {
    <10, 10, -1>
    color      Red
    spotlight
    radius     12
    falloff    14
    tightness  10
    area_light <1, 0, 0>, <0, 0, 1>, 3, 3
    adaptive   1
    jitter
    point_at   <2, 0, 0>
}
light_source {
    <-12, 10, -1>
    color      Blue
    spotlight
    radius     12
    falloff    14
    tightness  10
    area_light <1, 0, 0>, <0, 0, 1>, 3, 3
    adaptive   1
    jitter
    point_at   <-2, 0, 0>
}



// objekt vytvořený z písmen, jejichž tvary jsou přečteny z externího souboru s fontem
text {
    ttf                                  // formát s uloženým fontem
    "crystal.ttf",                       // soubor s fontem dodávaný současně s POV-Rayem
    "root.cz",                           // text, který se má vytvořit
    0.5,                                 // hloubka textového objektu
    0                                    // mezera mezi znaky
    texture {                            // textura, kterou je objekt pokrytý
        DMFLightOak
        scale 0.5
    }
    scale 2.5                            // změna měřítka textového objektu
    translate <-4, 0, -1>                // posun textového objektu
}



// otexturovaná koule
sphere {
    <0,-1,0>, 1                          // pozice středu a poloměr
    texture {                            // textura, kterou je objekt pokrytý
        Sapphire_Agate
    }
    translate <1.5, 0, -2>               // posun koule ve scéně
}



// kvádr, do kterého je celá scéna uzavřena
box {
    <-12,-2,-12>, <20, 20, 8>
    texture {
        pigment {                        // šachovnicová textura
            checker                      // vyvedená ve stupních šedi
            color rgb<0.1, 0.1, 0.1>
            color rgb<0.5, 0.5, 0.5>
        }
        finish {                         // odlesky a odrazy na povrchu
            diffuse 0.7
            reflection 0.2
        }
    }
}



// ------------------------------------------------------------
// finito
// ------------------------------------------------------------ 
povray1403

Obrázek 3: Druhý demonstrační příklad po vykreslení v POV-Rayi

4. Třetí demonstrační příklad – viditelný světelný zdroj

Pomocí malého triku lze v POV-Rayi některý světelný zdroj zviditelnit. K tomuto účelu se v definici světelného zdroje přidává klíčové slovo looks_like, za nímž je uvedený tvar objektu. Je důležité si uvědomit, že skutečný tvar zdroje se od viditelného může lišit, ale naším cílem by mělo být se co nejvíce oběma tvary k sobě přiblížit. Ve třetím demonstračním příkladu je využita předdeklarace objektu pomocí konstrukce #declare, takže se po slovu looks_like pouze zadá jméno již existujícího objektu. Samotný tvar světelného zdroje je poměrně jednoduchý – jedná se o žárovku složenou ze tří základních objektů – koule a válec zhruba odpovídají skleněné části, druhý válec pak objímce, ve které je žárovka uchycena. Opět následuje zdrojový kód příkladu:

// ------------------------------------------------------------
// Třetí demonstrační příklad na použití světelných zdrojů
// v prostorových scénách vykreslovaných POV-Rayem.
//
// Zviditelněný světelný zdroj
//
// rendering lze spustit příkazem:
//     povray +W800 +H600 +B100 +FN +D +Iscena.pov +Oscena.png
// (pro náhled postačí zadat povray scena.pov)
// ------------------------------------------------------------

#include "colors.inc"
#include "textures.inc"

// nastavení kamery
camera {
    location  <-4, 3, -9>                // pozice kamery
    look_at   <0, 0, 0>                  // bod, na který se kamera dívá
    angle 48                             // zorný úhel
}

// definice tvaru viditelné části světelného zdroje
#declare Lightbulb = union {
    merge {
        sphere { <0,0,0>,1 }
        cylinder {
            <0,0,1>, <0,0,0>, 1
            scale <0.35, 0.35, 1.0>
            translate  0.5*z
        }
        texture {
            pigment {color rgb <1, 1, 1>}
            finish {ambient .8 diffuse .6}
        }
    }
    cylinder {
        <0,0,1>, <0,0,0>, 1
        scale <0.4, 0.4, 0.5>
        texture { Brass_Texture }
        translate  1.5*z
    }
    rotate -90*x
    scale .5
}



// zviditelněný světelný zdroj
light_source {
    <0, 2.2, -3>
    color White
    area_light <1, 0, 0>, <0, 1, 0>, 5, 5
    adaptive 1
    jitter
    looks_like { Lightbulb }
}



// objekt vytvořený z písmen, jejichž tvary jsou přečteny z externího souboru s fontem
text {
    ttf                                  // formát s uloženým fontem
    "crystal.ttf",                       // soubor s fontem dodávaný současně s POV-Rayem
    "root.cz",                           // text, který se má vytvořit
    0.5,                                 // hloubka textového objektu
    0                                    // mezera mezi znaky
    texture {                            // textura, kterou je objekt pokrytý
        DMFLightOak
        scale 0.5
    }
    scale 2.5                            // změna měřítka textového objektu
    translate <-4, 0, -1>                // posun textového objektu
}



// otexturovaná koule
sphere {
    <0,-1,0>, 1                          // pozice středu a poloměr
    texture {                            // textura, kterou je objekt pokrytý
        Sapphire_Agate
    }
    translate <1.5, 0, -2>               // posun koule ve scéně
}



// kvádr, do kterého je celá scéna uzavřena
box {
    <-12,-2,-12>, <20, 20, 8>
    texture {
        pigment {                        // šachovnicová textura
            checker                      // vyvedená ve stupních šedi
            color rgb<0.1, 0.1, 0.1>
            color rgb<0.5, 0.5, 0.5>
        }
        finish {                         // odlesky a odrazy na povrchu
            diffuse 0.7
            reflection 0.2
        }
    }
}



// ------------------------------------------------------------
// finito
// ------------------------------------------------------------ 
povray1404

Obrázek 4: Třetí demonstrační příklad po vykreslení v POV-Rayi

5. Phongův osvětlovací model

Základ pro výpočet osvětlení jednotlivých bodů na povrchu těles představuje v POV-Rayi takzvaný Phongův osvětlovací model, který je ovšem rozšířen o další koeficienty, se kterými se v původním modelu nepočítalo. Phongův osvětlovací model je použitý v mnoha 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“). Mezi složitější modely patří například světelný model Cook-Torrancův, který je taktéž v některých raytracerech použit.

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), 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. V Phongově osvětlovacím modelu se dopadající světlo na povrchu tělesa rozkládá do tří světelných složek: ambientní složky (ambient light), difúzní složky (diffuse light) a odlesků (specular light). V tomto modelu se pro jednoduchost celková intenzita světla počítá zvlášť pro každou barevnou složku z barvového modelu RGB (red, green, blue), což je sice jednoduché, ale ve skutečnosti nekorektní.

6. Výpočet osvětlení s využitím Phongova osvětlovacího mo­delu

Pro výpočet osvětlení s využitím Phongova osvětlovacího modelu se používá následující vztah, který je aplikován na každou barevnou složku zvlášť, ve skutečnosti jsou tedy počítány intenzity Ired, Igreen a Iblue:

I=caIa+cdId(NL)+c­sIs(VR)n

Význam jednotlivých členů v tomto na první pohled složitém vztahu je následující:

  • I představuje celkovou intenzitu světla tak, jak je vnímána uživatelem. Ve skutečnosti se vždy spočítají tři na sobě nezávislé barevné složky R, G, B, (červená, zelená, modrá) takže se předchozí vztah počítá třikrát.
  • Ia představuje intenzitu ambientní složky světla, tj. té části světla, která na osvětlované těleso dopadá ze všech směrů rovnoměrně. Intenzita odraženého světla (tj. součinu caIa) je nezávislá na vzájemné poloze zdroje, tělesa a pozorovatele, čehož je mj. využito v radiozitní metodě (ale to již předbíháme).
  • Id představuje intenzitu difúzní složky světla, tj. té části světla, která dopadá na těleso z jednoho světelného zdroje (ať už bodového, směrového či plošného) a odráží se do všech směrů rovnoměrně. Intenzita odraženého světla (tj. součinu cdId(NL)) je závislá na vzájemné poloze normály stěny tělesa N a vektoru dopadu světla L (viz další text).
  • Is představuje intenzitu odlesků, tj té části světla, která dopadá na těleso z jednoho světelného zdroje (opět může jít buď o bodový nebo o směrový zdroj světla) a odráží se převážně v jednom směru podle zákona odrazu světelných paprsků. Intenzita tohoto odraženého světla závisí na vzájemné poloze světelného zdroje, povrchu tělesa a pozice pozorovatele.
  • ca je koeficient (resp. faktor) materiálu pro ambientní složku světla. Pro běžné materiály nabývá tento koeficient hodnot v rozmezí 0 až 1, kde nulová hodnota znamená, že se ambientní světlo od materiálu vůbec neodráží, hodnota 1 naopak nastavuje úplnou odrazivost.
  • cd je koeficient materiálu pro difúzní složku světla. Pro běžné materiály nabývá tento koeficient hodnot v rozmezí 0 až 1 s podobným významem jako u předchozího koeficientu. Ve většině případů lze ambientní a difúzní koeficient materiálu nastavit na stejnou hodnotu.
  • cs je koeficient odlesků s vlastnostmi podobnými jako u předchozích dvou koeficientů. Zde je nutné si uvědomit, že ve skutečnosti každý koeficient nastavujeme třikrát pro tři barevné složky RGB. Hodnota těchto koeficientů potom udává barvu materiálu při osvětlení bílým světlem, protože pouze bílé světlo je nastaveno na hodnotu (1.0, 1.0, 1.0). Při jiném osvětlení se mezi sebou pronásobí intenzity složek světelného zdroje a koeficienty materiálů, takže například sytě červený objekt bude v sytě modrém světle po vykreslení na obrazovce černý!
povray1405

Obrázek 5: Čtveřice vektorů použitých v Phongově osvětlovacím modelu

  • V součinu NL (skalárním) je použita normála k povrchu tělesa N a vektor ze světelného zdroje do bodu na povrchu tělesa, jehož barvu počítáme. Pokud jsou tyto vektory lineárně závislé (tj. rovnoběžné), je světelný zdroj umístěn kolmo nad povrchem tělesa a tím pádem je difúzní složka světla nejvíce intenzivní. Význam těchto dvou vektorů je zobrazen na obrázku. Ještě před výpočtem skalárního součinu NL musí být oba vektory normalizovány, tj. jejich velikost musí být jednotková, což za nás POV-Ray provede automaticky.
  • V součinu VR je použit vektor ideálně odraženého paprsku R a vektor vedoucí z pozice pozorovatele do bodu na povrchu tělesa V, jehož barvu počítáme. Vektor R lze vypočítat ze znalosti vektorů L (vektor vedoucí ke světelnému zdroji) a N (normála k povrchu) – postup je naznačen na dalším obrázku. Význam těchto dvou vektorů je zobrazen na předchozím obrázku. Podobně jako u vektorů N a L, i vektory V a R musí být normalizovány. Význam tohoto součinu je opět zřejmý – odrazy uvidíme s maximální intenzitou v místě, které je zrcadlově symetrické se zdrojem světla.
povray1406

Obrázek 6: Způsob výpočtu odraženého paprsku R

  • n je exponent u výrazu (VR)n, který udává míru lesklosti tělesa. Difúzní těleso bude mít exponent nulový, vysoce lesklé těleso zde může mít hodnotu například 50. Čím vyšší je hodnota tohoto exponentu, tím jsou odlesky na tělese menší (plochou), ale intenzivnější. Vliv velikosti exponentu na lesklosti je zobrazený na třetím obrázku této kapitoly.
povray1407

Obrázek 7: Vliv koeficientu n na změnu intenzity odlesků

7. Specifikace parametrů Phongova osvětlovacího modelu v POV-Rayi

Intenzita světla, tj. koeficienty Ia, Id a Is, se nastavují buď při zápisu jednotlivých světelných zdrojů, popř. (u ambientní složky) se jedná o globální nastavení platné pro celou scénu. Naopak koeficienty ca, cd, cs a n se specifikují pro každé těleso (resp. jeho povrch) zvlášť. K tomuto účelu slouží uzel nazvaný finish, ve kterém je možné specifikovat několik číselných atributů, z nichž ty nejpoužívanější jsou vypsány v následujícím fragmentu kódu:

// 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
} 

Kromě těchto koeficientů je možné zadávat i některé koeficienty další (specular, roughness, metallic) atd., ty však již přesahují rámec klasického Phongova osvětlovacího modelu a budeme se jimi zabývat až v následujících částech tohoto seriálu. Prozatím si bez problémů vystačíme s oněmi čtyřmi základními koeficienty, které (spolu s barvou povrchu a barvou světelného zdroje) dovolují vytvářet velké množství různých typů povrchů.

Vidíme, že ambientní světlo může být zadáno přímo pomocí třísložkového vektoru, tj. zastoupením červené, zelené a modré barvy. Tato hodnota je znásobena s globální hodnotou představující intenzitu všesměrového světla (viz předchozí část tohoto seriálu). Implicitně je ambientní složka nastavena na hodnotu 30%, což znamená, že jsou částečně viditelné i ty části těles, které se nachází ve stínu (to většinou odpovídá skutečnosti).

Koeficient difúzní složky diffuse je již specifikován hodnotou ležící v rozsahu 0.0 až 1.0. Nulová hodnota značí, že difúzní složka bude nulová, čímž se opticky celá scéna „zploští“. Koeficient odrazivé složky phong taktéž leží v rozsahu 0.0 až 1.0 a má tentýž význam: 0.0 značí, že se odrazivá složka na povrchu neprojeví, 1.0 odpovídá sto procentům. Koeficientem phong_size se řídí velikost a intenzita odlesků. Vyšší hodnota vede sice ke zmenšení „stopy“ odlesku, ale současně ke zvětšení jeho kontrastu. Implicitní hodnota je rovna 40, což zhruba odpovídá optickým vlastnostem průměrného plastu. Nižší hodnoty lze použít pro materiály, jako je kámen či dřevo, hodnoty vyšší (100–250) naopak pro kovy a skla.

UX DAy - tip 2

8. Obsah následující části seriálu

V další části seriálu o raytraceru POV-Ray si popíšeme jednoduché i složitější typy procedurálních textur, protože právě ty tvoří základ pro tvorbu realistických povrchů, například dřeva, mramoru, textilií apod. S POV-Rayem je dodáváno i větší množství souborů, ve kterých je již velké množství různých kvalitních textur vytvořeno. I obsahem těchto souborů a způsobem jejich (legálního) použití ve vlastních scénách se budeme příště zabývat.

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.