Hlavní navigace

Animace v POV-Rayi

9. 9. 2008
Doba čtení: 11 minut

Sdílet

V seriálu o programu POV-Ray jsme se doposud zabývali pouze tvorbou statických obrázků. Tento raytracer však umožňuje poměrně snadno pochopitelným způsobem, dokonce bez podpory externích aplikací, vykreslovat i animované sekvence. Právě vytvářením animací se budeme v dnešní části zabývat.

Obsah

1. Raytracer POV-Ray a tvorba animací
2. Interní proměnná clock a způsob jejího nastavení
3. První demonstrační příklad – animace rotace tělesa
4. Druhý demonstrační příklad – změna parametrů procedurální textury a složená rotace
5. Třetí demonstrační příklad – animace vodní hladiny
6. Výsledné animace
7. Obsah následující části tohoto seriálu

1. Raytracer POV-Ray a tvorba animací

V předchozích částech seriálu o raytraceru POV-Ray jsme si teoreticky i na mnoha demonstračních příkladech ukázali, jakým způsobem je možné zapsat a následně vykreslit (vyrendrovat) statickou trojrozměrnou scénu. POV-Ray však lze použít i pro tvorbu animací, které mohou být vytvořeny mnoha způsoby. V případě, že je pro vymodelování scény i definici její animace použit vhodný externí program (CAD, modelovací program typu KPovModeler, Moray, Wings 3D či specializovaná aplikace), je výsledkem práce tohoto programu většinou sada zdrojových souborů zapsaných v syntaxi POV-Raye a určených pro rendering. Výsledkem zpracování každého souboru POV-Rayem je jeden obrázek, který může být následně zařazen do vytvářené animace. Samotné spojení vykreslených obrázků (snímků) do animace je již nutné vyřešit jinými programovými prostředky, lze například použít existující kodéry vytvářející soubory dle normy MPEG-1, 2, 4, animace ve formátu FLI, Flash, animované GIFy atd.

Tento přístup k tvorbě animací je sice velmi flexibilní, protože každý zdrojový soubor může mít libovolný obsah zcela nezávislý na ostatních souborech, ovšem v praxi vyžaduje použití externího modelovacího programu, jelikož ruční úpravy v sadě zdrojových kódů jsou velmi pracné a samozřejmě také nepřehledné. Použití tohoto způsobu je zřejmé: POV-Ray lze využít jako vykreslovací back-end pro prakticky jakýkoli modelovací program, který díky spojení s POV-Rayem produkuje velmi kvalitní výsledky za relativně nízkou cenu (myšleno ve smyslu TCO, pořizovací cena raytraceru je nulová).

Dokonce je možné (a v praxi byla tato možnost již mnohokrát uplatněna), vytvořit takzvanou renderovací farmu, což může být počítačová síť složená buď ze specializovaných počítačů (např. Blade, vyzkoušena byla i serverovna plná vyřazených PlayStation 2 :-) nebo běžných desktopových stanic, na kterých se provádí paralelní výpočet výsledné animace. Jeden z počítačů celý výpočet řídí, tj. dodává jednotlivým výpočetním uzlům zdrojové soubory, které lokální POV-Ray umístěný v každém uzlu vykreslí a následně vrátí výsledný snímek. Lze použít i POV-Ray upravený pro PVM (Parallel Virtual Machine) či výpočet distribuovat v rámci Internetu i na vzdálené počítače. Předností je opět nízké TCO a také malé nároky POV-Raye na použitý hardware – k běhu není vyžadována ani grafická karta ani pevný disk, výpočet lze spustit z operační paměti a pro získání zdrojové scény a uložení výsledného obrázku použít například NFS.

2. Interní proměnná clock a způsob jejího nastavení

Výše uvedený způsob tvorby animací s pomocí POV-Raye však není jediný možný. V mnoha případech si totiž vystačíme pouze se schopnostmi samotného raytraceru bez nutnosti spouštět externí programy, přičemž se pro definici animací použije pouze vhodný textový editor. Někteří grafici si navíc vytváří zevrubný náčrtek animované scény na čtverečkovaném papíru, což někdy bývá praktičtější a také rychlejší, než použití modelovacího programu. Tento způsob samozřejmě není praktické použít ve všech situacích, ale jak bude patrné z demonstračních příkladů, mnohdy lze i se skrovnými prostředky dosáhnout uspokojivých výsledků.

Pro účely „ručního“ vytváření animací se v naprosté většině případů využívá dvou specifických vlastností POV-Raye. Při volání tohoto raytraceru je možné přímo na příkazové řádce specifikovat hodnotu interní proměnné clock, kterou lze při popisu scény použít. Několikeré volání POV-Raye pro stejnou scénu, pouze se specifikací odlišné hodnoty této proměnné má za následek cílenou změnu ve výsledném snímku.

Druhou specifickou vlastností POV-Raye, jejž se při tvorbě animací používá snad ještě častěji, je možnost automatické změny interní proměnné clock. Hodnota této proměnné je většinou nastavována samotným POV-Rayem tak, aby se pro zadaný počet snímků tato proměnná postupně a s konstantním přírůstkem zvyšovala od hodnoty 0,0 do hodnoty 1,0. Rozdíl mezi jednotlivými hodnotami (takzvaný krok) je automaticky vypočten v závislosti na tom, kolik snímků animace má být vytvořeno. Důležité je, že uživatel POV-Ray zavolá pouze jedenkrát (s vhodně nastavenými parametry) a raytracer automaticky začne s výpočtem daného počtu snímků, přičemž každý snímek uloží do zvláštního souboru, za jehož jméno je připojeno pořadové číslo. Toto číslo se většinou využije při následném skládání snímků do animace, protože programy určené pro tvorbu animací či videa dokážou snímky automaticky seřadit na základě jejich jména.

Následuje výpis parametrů příkazové řádky, které ovlivňují způsob automatického nastavování hodnot proměnné clock:

Parametr Význam parametru
+KFIn první snímek bude mít číslo n
+KFFn poslední snímek bude mít číslo n
+KIn.n hodnota clock na prvním snímku bude nastavena na n.n
+KFn.n hodnota clock na posledním snímku bude nastavena na n.n

V naprosté většině případů (výjimku tvoří stav, kdy se na sebe napojují dvě nebo více animací) lze vystačit pouze se zadáním celkového počtu snímků, všechny ostatní parametry jsou na základě této hodnoty korektně dopočítány. Důležité přitom je, že počet snímků nijak nemění vlastní průběh animace, pouze míru změn scény mezi jednotlivými snímky (první snímek bude mít hodnotu clock=0.0, prostřední snímek clock=0.5, snímek poslední pak clock=1.0 atd.). To mj. znamená, že je možné při tvorbě scény pro náhledy použít malý počet snímků a ve výsledku počet zvýšit, ideálně na hodnoty, které se přibližují reálnému videu (24 popř. 25 snímků za sekundu, časování provádí program, který video tvoří).

3. První demonstrační příklad – animace rotace tělesa

V prvním demonstračním příkladu je ukázána velmi jednoduchá animace, ve které je zobrazeno rotující těleso vymodelované pomocí CSG operace rozdílu (difference). Animace je cyklická, tj. poslední snímek plynule navazuje na snímek první. To znamená, že v průběhu celé animace musí být těleso otočeno o 360° nebo o celočíselné násobky 360°. Vzhledem k tomu, že interní proměnná clock nabývá při vykreslování jednotlivých snímků hodnot v intervalu od nuly do jedné, je nutné pro korektní rotaci o 360° použít přepočet, který je v tomto případě velmi snadný:

// animace rotace výsledného "dvojtělesa"
    rotate <0,clock*360,0> 
povray2701

Obrázek 1: První snímek animace

Povšimněte si také, že jednotlivé lineární transformace (konkrétně se jedná o dvojici rotací) je možné skládat:

rotate <25,0,0>
    // animace rotace výsledného "dvojtělesa"
    rotate <0,clock*360,0> 
povray2702

Obrázek 2: Animace se nachází v polovině

Zdrojový kód prvního demonstračního příkladu má tvar:

// ------------------------------------------------------------
// Aplikace CSG operace rozdílu koule a krychle s přidanou
// jednoduchou animací - rotací tělesa.
//
// Založeno na souboru původně vytvořeném Danem Farmerem (leden 2002)
//
// rendering lze spustit příkazem:
//     povray +W800 +H600 +B100 +FN +D +Iscena1.pov +Oscena1.png
//     (pro náhled postačí zadat povray scena1.pov)
// animaci lze vytvořit přidáním parametru:
//     +KFFpočet_snímků
// ------------------------------------------------------------

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

#declare VEL=1.45;                       // velikost krychle

difference {
    box {
        <-VEL, -VEL, -VEL>               // jeden z vrcholů krychle na tělesové úhlopříčce
        < VEL,  VEL,  VEL>               // druhý z vrcholů krychle na tělesové úhlopříčce
        texture {                        // textura - povrch krychle
            T_Glass1                     // definováno v externím souboru
            pigment {
                color green 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
            }
        }
    }
    sphere {
        <0, 0, 0>,                       // souřadnice středu koule
        1.8                              // poloměr koule
        interior {                       // vlastnosti "vnitřku" koule
            caustics 1.0
            ior 1.5
        }
        texture {                        // textura - povrch koule
            T_Glass1                     // definováno v externím souboru
            pigment {
                color green 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
            }
        }
    }
    rotate <25,0,0>
    rotate <0,clock*360,0>               // animace rotace výsledného "dvojtělesa"
}

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

Obrázek 3: Poslední snímek animace

4. Druhý demonstrační příklad – změna parametrů procedurální textury a složená rotace

Ve druhém demonstračním příkladu je ukázána tvorba nepatrně složitější animace. Ve scéně se nachází dvojice koulí, které jsou pokryty poloprůhlednými procedurálními texturami. Pravá koule je na základě měnící se lokální proměnné clock otáčena, a to tak, že se v průběhu celé animace otočí dvakrát okolo x-ové osy, třikrát okolo y-ové osy a jedenkrát okolo osy z-ové. Sice by bylo možné tuto transformaci rozepsat na tři po sobě jdoucí rotace (lineární transformace lze obecně skládat přičemž ovšem záleží na jejich pořadí), všechny tři transformace je však v tomto případě možné zapsat i jediným příkazem, jelikož na sobě nejsou lineárně závislé:

    rotate <clock*2*360, clock*3*360, clock*360> 
povray2704

Obrázek 4: První snímek animace

Animace levé koule spočívá ve změně jednoho z parametrů procedurální textury. Jedná se o parametr offset a způsob jeho nastavení je poněkud složitější. Interní proměnná clock je nejprve vynásobena hodnotou 360, tj. v prvním snímku animace bude mít nulovou hodnotu a ve snímků posledním hodnotu 360. Dále je na takto vypočtenou hodnotu aplikována zabudovaná funkce radians, která údaj ve stupních převede na radiány. Takto získaná hodnota je použita ve funkci sin (sinus), výsledek je vynásoben 1,1 (změna amplitudy) a posunut taktéž o hodnotu 1,1 (změna offsetu) – to je nutné provést z toho důvodu, aby parametr offset byl vždy kladný:

    offset 1.1+1.1*sin(radians(clock*360)) 
povray2705

Obrázek 5: Animace se nachází v polovině

Zdrojový kód dnešního druhého demonstračního příkladu má tvar:

// ------------------------------------------------------------
// Druhý demonstrační příklad:
// použití průhlednosti při vykreslování procedurálních textur
// bozo a crackle s přidanou animací - rotací tělesa a
// změnou parametrů procedurální textury.
//
// rendering lze spustit příkazem:
//     povray +W1024 +H768 +B100 +FN +D +Iscena2.pov +Oscena2.png
//     (pro náhled postačí zadat povray scena1.pov)
// animaci lze vytvořit přidáním parametru:
//     +KFFpočet_snímků
// ------------------------------------------------------------

#version 3.0
global_settings {
    assumed_gamma 2.2
}

#include "colors.inc"

camera {                                 // nastavení kamery
    location <100,50,50>                 // pozice kamery v prostoru
    direction z*1.2                      // směr pohledu kamery
    look_at <0,25,0>
}

light_source {                           // světelný zdroj
    <40,500,300>                         // pozice světelného zdroje
    color White*2                        // barva zdroje
}

plane {                                  // podkladová rovina
    y,0
    pigment {
        White
    }
}

sphere {                                 // první těleso s poloprůhlednou texturou
    <0,25,-30>, 25
    texture {
        pigment {
            crackle                      // typ procedurální textury
            color_map {                  // barvová mapa
                [0.0 White]
                [0.1 Wheat]
                [0.2 Red]
                [0.3 Clear]              // postupný přechod mezi červenou a průhlednou
                [1.0 Clear]              // zcela průhledná barva
            }
            offset 1.1+1.1*sin(radians(clock*360))
            scale 8                      // zvětšení textury
        }
    }
}

sphere {                                 // druhé těleso s poloprůhlednou texturou
    <0,0,0>,25
    texture {
        pigment {
            bozo                         // typ procedurální textury
            color_map {
                [0.0 Red]
                [0.2 Wheat]
                [0.4 Blue]               // plynulý přechod mezi modrou a průhlednou
                [0.5 Clear]              // zcela průhledná barva
                [1.0 Clear]              // zcela průhledná barva
            }
            scale 7                      // zvětšení textury
        }
    }
    rotate <clock*2*360, clock*3*360, clock*360>
    translate <0,25,30>
}

fog {                                    // mlha na pozadí scény
    White distance 600
}

// ------------------------------------------------------------
// finito
// ------------------------------------------------------------ 
povray2706

Obrázek 6: Poslední snímek animace

5. Třetí demonstrační příklad – animace vodní hladiny

povray2707

Obrázek 7: První snímek animace

Ve třetím příkladu je ukázána jednoduchá forma animace vodní hladiny. Samotná hladina je tvořena geometricky dokonalou rovinou na níž je při vykreslování aplikována modulace normálových vektorů neboli nám již známý bump mapping. Jelikož je pro modulaci normálových vektorů použita procedurální textura, není problém nějaký parametr této textury ovlivnit funkcí závislou na hodnotě interní proměnné clock. Nejprve je modifikátorem sine_wave nastavena sinusová závislost posunu normálového vektoru na hodnotě vypočtené pomocí procedurální textury a posléze je proveden posun výstupní hodnoty procedurální textury parametrem phase:

    sine_wave
    phase clock 
povray2708

Obrázek 8: Animace se nachází v polovině

Zdrojový kód třetího příkladu již z velké části známe:

// ------------------------------------------------------------
// Třetí demonstrační příklad.
// Ukázka použití procedurální textury "bumps" pro tvorbu vodní hladiny
// spolu s její animací.
//
// Persistence Of Vision raytracer version 3.5 sample file.
// By Dan Farmer
// Parabolic arches on the water.  Is this the St. Louis McDonalds?
// Enhanced for POV-Ray 3.1
//
// -w320 -h240
// -w800 -h600 +a0.3
// ------------------------------------------------------------

global_settings {
    assumed_gamma 2.2
    max_trace_level 5
}

#include "colors.inc"
#include "shapes.inc"
#include "textures.inc"
#include "metals.inc"
#include "skies.inc"

camera {
    location <60.0, 0.0, -135.0>
    direction <0.0, 0.0, 2.0>
    up  <0.0, 1.0, 0.0>
    right <4/3, 0.0, 0.0>
    look_at <0.0, 0.0, 0.0>
}

// Light
light_source {<200.0, 200.0, -150.0> colour red 1 green .5 }

#declare New_Sky = sky_sphere { S_Cloud2 }

sky_sphere { New_Sky }                      // changed by dmf '95

// Define the ocean surface
plane { y, -10.0
    texture {
        T_Chrome_2D
        normal {                         // bump mapa pro hladinu
            waves 0.05
            frequency 5000.0
            scale 3000.0
            sine_wave
            phase clock
        }
    }
}


// Create the arches using CSG difference between two "squashed" paraboloids
difference {
    object { Paraboloid_Y
        scale <20.0, 20.0, 5.0>
        rotate 180*x
        texture { T_Chrome_3C }
    }
    object { Paraboloid_Y
        scale <18.0, 20.0, 18.0>
        rotate 180*x
        translate -2*y
        texture { T_Copper_3C }
    }
    translate <0.0, 30.0, -25.0>
}

difference {
    object { Paraboloid_Y
        scale <20.0, 20.0, 5.0>
        rotate 180*x
        texture { T_Chrome_3C }
    }
    object { Paraboloid_Y
        scale <18.0, 20.0, 18.0>
        rotate 180*x
        translate -2*y
        texture { T_Copper_3C }
    }
    translate <0.0, 30.0, 50.0>
}

// ------------------------------------------------------------
// finito
// ------------------------------------------------------------ 
povray2709

Obrázek 9: Poslední snímek animace

6. Výsledné animace

povray2710

Obrázek 10: První demonstrační příklad

povray2711

Obrázek 11: Druhý demonstrační příklad

povray2712

Obrázek 12: Třetí demonstrační příklad

CS24_early

7. Obsah následující části tohoto seriálu

I v následující části seriálu o raytraceru POV-Ray se budeme zabývat tvorbou animací. Ukážeme si některé další možnosti využití interní proměnné clock, především ve spojení s poněkud složitějšími matematickými výrazy, funkcemi, ale i programovými konstrukcemi typu podmíněný příkaz a smyčka (i tyto spíše programátorské nástroje POV-Ray podporuje, zejména v třetí verzi došlo ke znatelnému vylepšení možností tvorby pokročilých maker). Také si podrobněji představíme už dříve zmiňovaný simulátor částicových systémů nazvaný Rune's Particle System, který je naprogramovaný přímo v POV-Rayi a proměnnou clock samozřejmě taktéž při výpočtu animovaných sekvencí využívá.

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.