Obsah
1. Optické vlastnosti průhledných těles
2. Index lomu
3. První demonstrační příklad – změna indexu lomu
4. Rozklad světla
5. Druhý demonstrační příklad – rozklad světla
6. „Světelná prasátka“
7. Třetí demonstrační příklad – scéna se světelnými prasátky
8. Obsah další části seriálu
1. Optické vlastnosti průhledných těles
V POV-Rayi lze poměrně jednoduchým způsobem vytvořit mnoho vizuálních efektů, které nastávají při průchodu světelných paprsků průhlednými tělesy. V první řadě se jedná o lom světla na rozhraní mezi okolním prostředím a tělesem. Úhel lomu paprsků je ovlivněn především takzvaným indexem lomu, který je možné specifikovat pro každý objekt vložený do vytvářené trojrozměrné scény. Na prvním ilustračním obrázku je zobrazeno několik sklenic s indexem lomu nastaveným na hodnotu 1,5:
Obrázek 1: Sklenice, na jejichž povrchu se lámou světelné paprsky
Dále lze simulovat rozklad světelných paprsků, který je možné pozorovat například na průhledných hranolech. Pomocí standardního raytracingu je rozklad světelných paprsků vypočítán sice nepřesně (při lomu se původní paprsek rozpadne na několik paprsků sekundárních, každý bude mít jinak ovlivněnou barvu i úhel lomu), zato však poměrně rychle – viz druhý ilustrační obrázek:
Obrázek 2: Simulace rozkladu světelných paprsků pomocí raytracingu
Druhý způsob výpočtu rozkladu světelných paprsků, který je mnohem přesnější a současně i pomalejší, spočívá ve využití dopředného sledování paprsků (photon mapping, direct tracing), což je technika, kterou si popíšeme v některé z následujících částí tohoto seriálu věnovaných pokročilým (a ne příliš známým) možnostem POV-Raye.
Obrázek 3: Simulace rozkladu světelných paprsků pomocí photon mappingu
V POV-Rayi je také možné velmi jednoduchým způsobem simulovat vznik světelných „prasátek“, které jsou způsobeny současným odrazem i lomem světla na rozhraní dvou materiálů. Opět se nejedná o fyzikálně zcela přesný výsledek, ovšem vizuální chyby se v tomto případě prakticky nedají nalézt, jelikož se jedná o fenomén vznikající typicky na rozhraní vzduch – voda při zvlněné hladině.
Obrázek 4: Netradičním způsobem pojatá vodní hladina
2. Index lomu
Velmi jednoduchým způsobem je možné u průhledných těles specifikovat index lomu. K nastavení všech optických vlastností vnitřků těles slouží uzel nazvaný interior, v němž je pro každé těleso možné změnit hodnotu několika konstant. Jednou z těchto konstant je i index lomu nazvaný krátce ior (index of refraction). Implicitní hodnotou indexu lomu je v POV-Rayi 1,0, což znamená, že k lomu světelných paprsků nedochází (stejný index lomu má totiž i okolní prostředí – vzduchoprázdno). Pro každou hodnotu větší než 1,0 již k lomu světelných paprsků dochází, například voda má index lomu roven 1,33, sklo 1,5 a diamant má velmi vysoký index lomu dosahující hodnoty 2,4. Pokud jsou do sebe vložena dvě tělesa složená z různých průhledných materiálů, bude úhel lomu světelných paprsků odvozen z indexů lomů obou materiálů. Například sklo ponořené do vody bude světlo lámat jinak než sklo ve vzduchu; tento jev si každý může ověřit při potápění. Poznamenejme, že index lomu je odvozen od poměru rychlosti šíření světla ve vakuu a daném materiálu.
Obrázek 5: Skleněný objekt vymodelovaný pomocí implicitních ploch (metaballs)
3. První demonstrační příklad – změna indexu lomu
V dnešním prvním demonstračním příkladu je vytvořeno pět průhledných objektů, přičemž každému objektu je přiřazen jiný index lomu. První objekt (umístěný na levé straně obrázku) má index lomu diamantu (ior=2,4), další dva objekty jsou vytvořeny z různých typů skel, čtvrtý objekt je vymodelován z vody a konečně poslední objekt (umístěný zcela vpravo) má index lomu nastavený na 1,000292, což je index lomu vzduchu. Aby byl vliv indexů lomů více patrný, je za každým průhledným objektem umístěna oranžová koule: celkem se tedy ve scéně nachází pět různých průhledných objektů a pět naprosto stejných oranžových koulí. Povšimněte si, že zatímco u prvních čtyř objektů jejich kulaté části fungují jako čočka, poslední objekt sice také lomí světelné paprsky, ale ve zcela zanedbatelné míře (index lomu vzduchu je prakticky stejný jako index lomu vzduchoprázdna). Lom je u tohoto objektu patrný pouze na textuře podlahy.
Obrázek 6: První demonstrační příklad po vykreslení v POV-Rayi
Následuje výpis zdrojového kódu prvního demonstračního příkladu:
// ------------------------------------------------------------
// První demonstrační příklad založený na zdrojovém souboru
// dodávaném společně s POV-Rayem.
//
// Ukázka lomu světelných paprsků na tělesech vytvořených
// z různých typů skel.
// ------------------------------------------------------------
global_settings {
max_trace_level 20 // maximální počet odrazů/lomů
assumed_gamma 2.2
}
#include "colors.inc"
#include "shapes.inc"
#include "textures.inc"
#include "glass.inc"
#include "consts.inc" // obsahuje mj. i indexy lomu
camera {
location <0, 5, -20> // pozice kamery v prostoru
direction z // směr kamery
angle 57 // zorný úhel
up <0.0, 1.0, 0.0> // vektor směřující vzhůru (část orientace kamery v prostoru)
right <4/3, 0.0, 0.0> // vektor směřující doprava
look_at <0, 1, 0>
}
// barva jednoho světelného zdroje
#declare Watts = color Gray25;
#declare Light_Distance = -50;
// několik světelných zdrojů sdružených do jednoho objektu
union {
light_source { <-6, 0, Light_Distance> color Watts }
light_source { <-4, 0, Light_Distance> color Watts }
light_source { <-2, 0, Light_Distance> color Watts }
light_source { < 0, 0, Light_Distance> color Watts }
light_source { < 2, 0, Light_Distance> color Watts }
light_source { < 4, 0, Light_Distance> color Watts }
light_source { < 6, 0, Light_Distance> color Watts }
rotate 60*x
pigment { White } // nemá žádný vliv na výsledek, jen pro zabránění warningu
}
// podlaha
plane {
y, -1 // orientace a vzdálenost od středu
pigment {
checker color HuntersGreen color SummerSky
scale <32000, 1, 2>
}
finish {
ambient 0.1
diffuse 0.6
}
}
// objekt, na kterém se bude zkoumat vliv indexu lomu
// skládá se z průhledné části a oranžové koule
#declare Hummer =
union {
// skleněná část objektu
union {
object { UnitBox }
object { Disk_Y translate 2*y }
sphere { <0, 4, 0>, 1 }
rotate 45*y
}
// oranžová koule umístěná za skleněnou částí
sphere { <0, 5, 20>, 1
texture {
finish { Shiny }
pigment { Orange }
}
}
}
// textura, která je přiřazena všem následujícím objektům
default { texture { T_Glass1 } }
// vložení všech pěti objektů do scény, každý objekt má jiný index lomu
object {
Hummer
translate -6*x
interior {
ior Diamond_Ior
}
}
object {
Hummer
translate -3*x
interior {
ior Flint_Glass_Ior
}
}
object {
Hummer
translate 0*x
interior {
ior Crown_Glass_Ior
}
}
object {
Hummer
translate 3*x
interior {
ior Water_Ior
}
}
object {
Hummer
translate 6*x
interior {
ior Air_Ior
}
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
4. Rozklad světla
S lomem světelných paprsků souvisí i jejich rozklad, který je možné pozorovat na krystalech vyrobených z materiálů, které mají vysoký index lomu (diamant a další drahokamy). V POV-Rayi lze rozklad světla simulovat buď pomocí klasického raytracingu, konkrétně nastavením atributu dispersion, nebo dopředným sledováním paprsků, které je sice mnohem pomalejší, na druhou stranu však produkuje přesnější výsledky. Dnes si popíšeme první možnost. V uzlu interior je možné specifikovat hodnotu atributu dispersion, která udává míru rozkladu světla na jednotlivé barvy duhy. Implicitní hodnota tohoto atributu je 1,0, což znamená, že k rozkladu nedochází. Dále je možné nastavit atribut dispersion_samples, jehož (celočíselná) hodnota ovlivňuje počet generovaných sekundárních paprsků – každý paprsek představuje jednu barvu z celého spektra. Čím vyšší je hodnota tohoto atributu, tím přesnější bude výsledek (přechody mezi barvami budou plynulé), ovšem zvýší se i doba potřebná pro výpočet.
Obrázek 7: Okolo odlesků diamantu je patrný rozklad světla
Jednoduchý rozklad světla lze vytvořit i na kouli, což je ukázáno v následujícím fragmentu kódu:
// 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 {
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
}
// tři světelné zdroje
light_source {
<-30, 11, 20> // pozice světelného zdroje
color White // barva světla
}
light_source {
< 31, 12, -20> // pozice světelného zdroje
color White // barva světla
}
light_source {
< 32, 11, -20> // pozice světelného zdroje
color LightGray // barva světla
}
// jediný uzavřený objekt ve scéně - skleněná koule
sphere {
<0, 0, 0>, // souřadnice středu koule
1.75 // poloměr koule
interior { // vlastnosti "vnitřku" koule
caustics 1.0
ior 1.5
dispersion 1.1
dispersion_samples 50
}
texture { // textura - povrch koule
T_Glass1 // definováno v externím souboru
pigment {
color red 0.90 green 0.90 blue 0.90 filter 0.85 // barva povrchu
}
finish { // optické vlastnosti materiálu
phong 1 // velikost a síla odlesků
phong_size 300
reflection 0.15 // odrazivost
}
}
}
// 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
}
}
}
5. Druhý demonstrační příklad – rozklad světla
Ve druhém demonstračním příkladu je ukázán rozklad světla na objektech různých tvarů. Jedná se o superelipsoidy (viz pátá část tohoto seriálu), které jsou vyrobeny z průhledného materiálu s indexem lomu nastaveným na hodnotu 1,4, tj. jedná se o materiál s vlastnostmi skla (sami si můžete vyzkoušet, jak bude scéna vypadat při nastavení indexu lomu na hodnotu 2,4, což odpovídá diamantu). Také míra rozkladu světla je nastavena na hodnotu 1,4, což vede k tomu, že se na hranách těles vytváří duhové odlesky. U některých objektů je patrné, že je světlo rozloženo jen do několika barev, protože implicitní hodnota atributu dispersion_samples je rovna pouze sedmi, tj. po dopadu na povrch tělesa se původní paprsek rozloží na sedm sekundárních paprsků, z nichž každý má nastavený odlišný barevný filtr. Zdrojový kód druhého demonstračního příkladu má tvar:
// ------------------------------------------------------------
// Druhý demonstrační příklad - rozklad světla na objektech
// různých tvarů.
// Několik superelipsoidů odvozených od základního tvaru krychle.
//
// rendering lze spustit příkazem:
// povray +W800 +H600 +B100 +FN +D +Isuper2.pov +Osuper2.png
// (pro náhled postačí zadat povray super2.pov)
// ------------------------------------------------------------
global_settings {
assumed_gamma 2.2
}
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 0.7 green 0.7 blue 0.7 // barva světelného zdroje
}
light_source { // druhý světelný zdroj
<0, 0, -10000> // pozice světelného zdroje
color red 0.7 green 0.7 blue 0.7 // barva světelného zdroje
shadowless
}
plane { // rovina tvořící pozadí scény
<0, 0, 1>, 3 // posun a orientace roviny
hollow on
texture {pigment {color red 1.0 green 1.0 blue 1.0}}
finish { // optické vlastnosti materiálu povrchu
ambient 0.1
diffuse 0.4
}
}
// pozice jednotlivých objektů ve scéně
#declare Row1 = +8;
#declare Row2 = +3;
#declare Row3 = 0;
#declare Row4 = -3;
#declare Row5 = -8;
#declare Col1 = -10;
#declare Col2 = -5;
#declare Col3 = 0;
#declare Col4 = +5;
#declare Col5 = +10;
// textura všech objektů
#declare Tex =
texture {
pigment {
color red 1 green 1 blue 1 filter 0.8
}
finish {
ambient 0.2 diffuse 0.4 phong 0.5 phong_size 5
}
}
// následují jednotlivé superelipsoidy
superellipsoid {
<0.0, 0.1> scale 1.6 rotate <-15, 30, 0> translate <Col1, Row1, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<0.0, 0.2> scale 1.6 rotate <-15, 30, 0> translate <Col2, Row1, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<0.0, 0.3> scale 1.6 rotate <-15, 30, 0> translate <Col3, Row1, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<0.0, 0.8> scale 1.6 rotate <-15, 30, 0> translate <Col4, Row1, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<0.0, 1.0> scale 1.6 rotate <-15, 30, 0> translate <Col5, Row1, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<0.0, 1.5> scale 1.6 rotate <-15, 30, 0> translate <Col1, Row2, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<0.0, 2.0> scale 1.6 rotate <-15, 30, 0> translate <Col2, Row2, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<0.0, 2.5> scale 1.6 rotate <-15, 30, 0> translate <Col3, Row2, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<0.0, 3.0> scale 1.6 rotate <-15, 30, 0> translate <Col4, Row2, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<0.0, 4.0> scale 1.6 rotate <-15, 30, 0> translate <Col5, Row2, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<2.0, 0.1> scale 1.6 rotate <-15, 30, 0> translate <Col1, Row4, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<2.0, 0.2> scale 1.6 rotate <-15, 30, 0> translate <Col2, Row4, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<2.0, 0.3> scale 1.6 rotate <-15, 30, 0> translate <Col3, Row4, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<2.0, 0.8> scale 1.6 rotate <-15, 30, 0> translate <Col4, Row4, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<2.0, 1.0> scale 1.6 rotate <-15, 30, 0> translate <Col5, Row4, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<2.0, 1.5> scale 1.6 rotate <-15, 30, 0> translate <Col1, Row5, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<2.0, 2.0> scale 1.6 rotate <-15, 30, 0> translate <Col2, Row5, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<2.0, 2.5> scale 1.6 rotate <-15, 30, 0> translate <Col3, Row5, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<2.0, 3.0> scale 1.6 rotate <-15, 30, 0> translate <Col4, Row5, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
superellipsoid {
<2.0, 4.0> scale 1.6 rotate <-15, 30, 0> translate <Col5, Row5, 0>
texture { Tex }
interior { ior 1.4 dispersion 1.4 }
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Obrázek 8: Druhý demonstrační příklad po vykreslení v POV-Rayi
6. „Světelná prasátka“
Současným odrazem i lomem světla na rozhraní dvou prostředí může docházet ke vzniku „světelných prasátek“ (caustics). Tohoto zajímavého světelného efektu je možné v POV-Rayi dosáhnout poměrně jednoduše – postačí v uzlu interior nastavit hodnotu atributu caustics na nenulovou hodnotu. Tento atribut typicky nabývá hodnot z rozsahu nula až jedna, ovšem je možné specifikovat i hodnoty větší než jednička. Implicitně je nastavena nulová hodnota, což tvorbu světelných prasátek zakáže a vykreslení celé scény se nepatrně zrychlí (ne však do takové míry, jako vypnutí rozkladu světla, to je výpočetně mnohem náročnější). Malé hodnoty atributu, které se pohybují v blízkosti nuly, vedou ke vzniku rozsáhlejších světlých ploch, zatímco hodnoty vyšší (jedna a více) způsobí vznik menších, ale zato výraznějších světelných prasátek. Důležité je nastavit atribut caustics u objektu, který má prasátka vrhat a ne u objektu, na kterém se zviditelňují.
Obrázek 9: Světelná prasátka vrhaná skleněnými objekty
7. Třetí demonstrační příklad – scéna se světelnými prasátky
V dnešním třetím demonstračním příkladu je ukázáno použití světelných prasátek, které mohou výrazně obohatit i scénu složenou z malého množství objektů. Testovací scéna má představovat pohled pod hladinou bazénu. Ve své jednodušší podobě se ve scéně nachází pouze dva objekty – dno bazénu a vodní hladina; v podobě složitější jsou pak ještě přidány stěny bazénu vymodelované pomocí jediného kvádru s nanesenou šachovnicovou texturou. Tvorba světelných prasátek je povolena a současně i nastavena při definici vodní hladiny. Kromě barvy hladiny je povoleno i modulování normálových vektorů (bump mapping), pro nějž je použita procedurální textura bumps. To spolu s nastaveným indexem lomu vody (ior 1.1) vede k nepravidelnému lomu paprsků na povrchu vodní hladiny, protože se při výpočtu lomeného paprsku vychází z orientace normálového vektoru, který je procedurální texturou modulován. Modifikátorem caustics 1.0 umístěným uvnitř uzlu interior je pak definována míra tvorby prasátek na dně bazénu a částečně i na jeho stěnách.
Obrázek 10: Třetí demonstrační příklad po vykreslení v POV-Rayi (do scény jsou zahrnuty i stěny bazénu)
Zdrojový kód třetího demonstračního příklad má tvar:
// ------------------------------------------------------------
// Třetí demonstrační příklad - vytvoření "prasátek" na dně
// bazénu vzniklých vlnkami na vodní hladině.
//
// rendering lze spustit poíkazem:
// povray +W800 +H600 +B100 +FN +D +Icaustic.pov +Ocaustic.png
// (pro náhled postaeí zadat povray caustic.pov)
// ------------------------------------------------------------
global_settings {
assumed_gamma 2.2
}
#include "colors.inc"
#include "textures.inc"
camera { // nastavení kamery
direction z // směr pohledu kamery
location <0, 6, -15> // umístění kamery
look_at <0, 2, 0> // bod, na který se kamera zaměřila
}
light_source { // nastavení světelného zdroje
<0, 50, 0> // pozice světelného zdroje
color White // barva světelného zdroje
}
plane { // dno bazénu
y, 0 // orientace roviny a její posun od počátku
pigment { // barva dna
Gray60
}
finish { // vypnutí odlesků
ambient 0.1
diffuse 0.7
}
}
// kvádr, do kterého je celá scéna uzavoena
/*
box {
<-10,-16,-16>, < 10, 200, 10>
texture {
pigment { // šachovnicová textura
checker
color <0.1, 0.3, 0.4>,
color <0.2, 0.5, 0.7>
}
finish { // odlesky a odrazy na povrchu
diffuse 0.7 // kvádru
reflection 0.1
ambient 0.1
}
}
}
*/
plane { // vodní hladina
y, 10 // orientace roviny a její posun od počátku
hollow on // jedná se o "prázdný" objekt, nikoli poloprostor
pigment { // barva hladiny
red 0.7 green 0.7 blue 1.0 filter 0.9
}
finish { // odrazivost
reflection 0.7
}
interior {
ior 1.1 // index lomu vody
caustics 1.0 // povolení "prasátek"
}
translate <5, 0, -10> // lineární transformace
normal { // vlny
bumps 0.5
}
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Obrázek 11: Třetí demonstrační příklad po vykreslení v POV-Rayi (stěny bazénu nejsou do scény zahrnuty)
8. Obsah další části seriálu
V následujícím pokračování seriálu o raytraceru POV-Ray si řekneme, jakým způsobem je pro něj možné vytvářet scény. Popíšeme si především některé volně dostupné modelovací programy, které je možné spolu s POV-Rayem využít, ale i další specializované nástroje, například generátory krajiny (terénu), generátory keřů a stromů, programy pro konverzi trojrozměrných dat z různých formátů do jazyka POV-Raye apod.
Obrázek 12: KPovRay modeller patří mezi celou řadu modelovacích programů, které dokáží vytvořit popis scén zpracovatelný POV-Rayem