Hlavní navigace

Vodní hladina vytvořená bump mappingem, mapa sklonů

5. 8. 2008
Doba čtení: 11 minut

Sdílet

V dnešní části seriálu o raytraceru POV-Ray si ukážeme využití modulace normálových vektorů (bump mappingu) při tvorbě vodní hladiny. Také si řekneme, jaký vliv má mapa sklonů (slope_map) na tvar hrbolků vytvořených pomocí modulace normálových vektorů a jak lze tuto mapu změnit.

Obsah

1. Vodní hladina vytvořená bump mappingem
2. Procedurální textury použitelné pro tvorbu vodní hladiny
3. První příklad – použití textury „waves“ pro tvorbu vodní hladiny
4. Druhý příklad – použití textury „bumps“ pro tvorbu vodní hladiny
5. Význam mapy sklonů (slope_map) při modulaci normálových vektorů
6. Specifikace mapy sklonů
7. Třetí příklad – změna mapy sklonů modulující normálové vektory

1. Vodní hladina vytvořená bump mappingem

V předchozí části tohoto seriálu jsme si teoreticky vysvětlili a na několika praktických demonstračních příkladech ukázali použití procedurálních textur při takzvaném bump mappingu neboli modulaci normálových vektorů. Tuto techniku je možné použít pro vykreslování povrchů s různými hrbolky, například při tvorbě plechových objektů, zdí s hrubou omítkou, kamenných zdí či podlah, povrchů cest i vozovek atd.

povray2301

Obrázek 1: Povrch vozovky na této scéně je vizualizován s využitím bump mappingu

Velmi často se bump mapping aplikuje také na roviny, které mají představovat vodní hladinu. Bump mapping sice nedokáže vytvořit skutečné vlny, které by měnily tvar vodní hladiny (pro tento účel by šlo použít například výškové pole – height field), ovšem v mnoha scénách nemusí být tato principiální nedokonalost bump mappingu na škodu, protože samotné vlny v mnoha scénách mají tak malou výšku, že nezvlnění vodního povrchu nemusí být vůbec patrné, především v těch případech, kdy je obrázek použit například ve filmu nebo animaci (pozorovatel nemá dost času na to, aby si uvědomil malé vizuální chyby, zejména v případě, že není odborníkem na počítačovou grafiku – viz například vyloženě pokažený rendering komínů ve filmu Titanic, kterého si snad žádný recenzent nevšiml).

povray2302

Obrázek 2: Vlny na této vodní hladině jsou pouze zdánlivé, což je patrné například při pohledu na místa, kde se vodní hladina dotýká trupu lodí (ovšem málokdo si této chyby všimne)

V dalším textu se budeme soustředit právě na vytvoření vodní hladiny pomocí bump mappingu.

2. Procedurální textury použitelné pro tvorbu vodní hladiny

Pro tvorbu zvlněné vodní hladiny, na které mají mít vlny tvar typických soustředných kruhů, je určena procedurální textura nazvaná příznačně waves. Pokud je tato textura použitá jako zdroj pro barevný vzorek, je poměrně nevýrazná, což je ostatně ukázáno i na následujícím obrázku, ovšem pro tvorbu bump map je naopak tato nevýraznost vítaná.

povray2303

Obrázek 3: Textura waves použitá jako zdroj pro barevný vzorek

Při tvorbě výše zobrazeného vzorku byl použit následující fragment kódu:

#version 3.0
global_settings {
    assumed_gamma 2.2
}

#include "colors.inc"

camera {                       // nastavení kamery
    orthographic               // bez perspektivy
    location < 0, 0, -1>       // pozice kamery
    right 4*x                  // šířka a výška snímané části scény
    up 4*y
    direction z                // směr pohledu kamery (k počátku)
}

light_source {                 // světelný zdroj
    <200, 200, -500>           // pozice
    color White                // barva
}

object {
    box {                      // testovací objekt - jednoduchý kvádr
        <-2,-2, 0>,
        < 2, 2, 1>
    }
    texture {
        pigment {
            waves
            scale 0.2
            color_map {        // náhrada původní barvové mapy
                [0.0 color Blue]      // hodnota 0 je dolní mezí, pro kterou lze specifikovat barvu
                [1.0 color White]
            }
            turbulence 0.0
        }
    }
    translate <0, 0, 0>
} 

V případě, že se mají vytvořit nepravidelné vlnky typické pro volnou vodní hladinu, lze využít dnes již klasickou procedurální texturu bumps, popř. i bozo, ovšem s nízkou či dokonce nulovou mírou turbulence. Pokud by byla textura příliš náhodná nebo měla velkou frekvenci opakování vzorků, byl by narušen zrcadlící charakter povrchu hladiny, což by mohlo vést k jejímu nepřirozenému vzhledu. Na dalším obrázku je zobrazena procedurální textura bumps použitá jako zdroj pro barevný vzorek:

povray2304

Obrázek 4: Textura bumps použitá jako zdroj pro barevný vzorek

Kód použitý pro tvorbu výše zobrazeného vzorku má tvar:

#version 3.0
global_settings {
    assumed_gamma 2.2
}

#include "colors.inc"

camera {                       // nastavení kamery
    orthographic               // bez perspektivy
    location < 0, 0, -1>       // pozice kamery
    right 4*x                  // šířka a výška snímané části scény
    up 4*y
    direction z                // směr pohledu kamery (k počátku)
}

light_source {                 // světelný zdroj
    <200, 200, -500>           // pozice
    color White                // barva
}

object {
    box {                      // testovací objekt - jednoduchý kvádr
        <-2,-2, 0>,
        < 2, 2, 1>
    }
    texture {
        pigment {
            bumps
            scale 0.5
            color_map {        // náhrada původní barvové mapy
                [0.0  color Blue]      // hodnota 0 je dolní mezí, pro kterou lze specifikovat barvu
                [1.0  color White]
            }
            turbulence 0.0
        }
    }
    translate <0, 0, 0>
} 

3. První příklad – použití textury „waves“ pro tvorbu vodní hladiny

V dnešním prvním demonstračním příkladu je ukázáno jak použití procedurální textury bozo při tvorbě mraků na obloze (pro získání vzorku samotné oblohy je využit gradientní přechod mezi dvojicí barev), tak i procedurální textury waves, která je využita pro modulaci normálových vektorů roviny tvořící vodní hladinu, ve které se odráží dvojice parabolických oblouků. Pokud vám oblouky připomínají skutečnou stavbu ze St. Louis, tak vězte, že se jedná o poněkud odlišný tvar, v obou případech má však objekt rozpětí oblouků shodné s jeho výškou. Z vykreslené scény je patrné, že změna normálových vektorů (které by v normálním případě, tj. bez modulace normálových vektorů, směřovaly ve všech místech roviny kolmo nahoru) se projeví jak na výpočtu osvětlení, tj. především stínů a odlesků, tak i při odrazu paprsků od vodní hladiny, takže se původní ideální zrcadlový odraz oblouků rozpadá tak, jak je tomu i ve skutečném světě (nebo se alespoň k originálu přibližuje). Ze specifikace bump mapy je dále patrné, že se frekvence procedurální textury 5000× zvýšila oproti originálu a také měřítko textury se liší od implicitní hodnoty:

// procedurální textura použitá pro modulaci normál
normal {
    waves 0.05
    frequency 5000.0
    scale 3000.0
} 
povray2305

Obrázek 5: První demonstrační příklad po vykreslení POV-Rayem

Zdrojový kód prvního demonstračního příkladu z velké míry vychází ze scény dodávané spolu s POV-Rayem, jejímž autorem je známý Dan Farmer:

// ------------------------------------------------------------
// První demonstrační příklad vykreslený s volbami -w1024 -h768 +a0.3
// Ukázka použití procedurální textury "waves" pro tvorbu vodní hladiny
//
// 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
        }
    }
}


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

Obrázek 6: Zcela pravidelné vlny nepůsobí příliš přirozeně, navíc se ve větší dálce objevuje nepříjemný alias

4. Druhý příklad – použití textury „bumps“ pro tvorbu vodní hladiny

Ve druhém demonstračním příkladu je použita stejná definice trojrozměrné scény, jako v příkladu prvním, tj. jsou vykresleny dva oblouky, z nichž každý je složen ze dvou paraboloidů odečtených pomocí CSG operací (Constructive Solid Geometry). Liší se pouze procedurální textura použitá pro modulaci normálových vektorů. Místo textury waves, která tvoří vzorek vhodný pro tvorbu kruhů na vodě, je použita procedurální textura bumps, určená především k  tvorbě nerovností na plechových tělesech. Ovšem pro vykreslení nepravidelných vlnek na vodní hladině je možné použít i tuto texturu, jak je to ostatně patrné i z obrázku vykresleného na základě druhého příkladu v POV-Rayi. Specifikace procedurální textury bumps, která je dvakrát zvětšena a jejíž hrbolky jsou naopak zmenšeny na pět procent původní (implicitní) hodnoty, má tvar:

// procedurální textura použitá pro modulaci normál
normal {
    bumps
    bump_size 0.05
    scale 2
} 

Následuje výpis zdrojového kódu druhého demonstračního příkladu:

// ------------------------------------------------------------
// Druhý demonstrační příklad vykreslený s volbami -w1024 -h768 +a0.3
// Ukázka použití procedurální textury "bumps" pro tvorbu vodní hladiny
//
// 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
            bumps
            bump_size 0.05
            scale 2
        }
    }
}


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

Obrázek 7: Druhý demonstrační příklad po vykreslení POV-Rayem

5. Význam mapy sklonů (slope_map) při modulaci normálových vektorů

Již v předchozí části tohoto seriálu jsme si popsali postup, který je využit v případě, že je na vykreslovaný povrch aplikována bump mapa, tj. jsou modulovány jeho normálové vektory. Ve zkratce je možné celý postup popsat následovně: nejprve je na základě souřadnic průsečíku paprsku s povrchem objektu získána hodnota z procedurální textury nebo z rastrového obrázku, který tvoří zdroj pro bump mapu. Načtená hodnota je následně použita pro vyhledání výšky hrbolku a jeho sklonu v takzvané mapě sklonů – slope_map. Teprve na základě údajů získaných z mapy sklonů je změněna orientace normálového vektoru, která je následně použita v Phongově osvětlovacím modelu při výpočtu odlesků a odrazů. Zatímco procedurální textura ovlivňuje tvar a rozmístění jednotlivých nerovností povrchu, lze pomocí mapy sklonů změnit zdánlivou výšku hrbolků, jejich sklon či dokonce samotný výškový profil hrbolku (například na vrcholech hrbolků je možné poměrně jednoduše vytvořit prohlubně).

povray2308

Obrázek 8: Objekt, jehož normálové vektory jsou modulovány procedurální texturou crackle

6. Specifikace mapy sklonů

Mapu sklonů je možné specifikovat pomocí uzlu slope_map, který je umístěn uvnitř uzlu normal. V uzlu slope_map je uloženo pole, které se do jisté míry podobá poli použitého v barvové mapě (color_map), ovšem vlastní hodnoty zde uložené mají poněkud odlišný význam. Každý prvek pole mapy sklonů začíná hodnotou ležící v rozsahu 0 až 1, protože výsledkem výpočtu funkce představující procedurální texturu je také hodnota z tohoto rozsahu (vstupní hodnotou do mapy sklonů je výstupní hodnota vypočtená pomocí procedurální textury). Následuje dvousložkový vektor, přičemž první složka představuje výšku hrbolku pro danou vstupní hodnotu a druhá složka pak sklon, přesněji řečeno směrnici sklonu – nulová hodnota značí rovinu, hodnota +1 sklon +45°, hodnota –1 sklon –45° atd. Výška by měla ležet v rozsahu 0 až 1, sklon sice teoreticky může nabývat jakékoli hodnoty, v praxi se však doporučuje dodržet interval od –3 do 3. Devátý obrázek byl vytvořen s pomocí následující mapy sklonů:

slope_map {                  // mapa sklonů
    [0   <0, 1>]       // nulová výška, sklon nahoru 45 stupňů
    [0.5 <1, 1>]       // maximální výška, stále stejný sklon
    [0.5 <1,-1>]       // zlom (na levé straně je stejná hodnota, jako na předchozím řádku)
    [1   <0,-1>]       // nulová výška, sklon dolů 45 stupňů
} 
povray2309

Obrázek 9: Objekt, jehož normálové vektory jsou modulovány procedurální texturou crackle s aplikovanou mapou sklonů

7. Třetí příklad – změna mapy sklonů modulující normálové vektory

Ve třetím demonstračním příkladu, který je vlastně replikou příkladu uvedeného v předchozí části tohoto seriálu, je ukázáno použití mapy sklonů, ve které jsou uložené hodnoty, s jejichž pomocí je vytvořena poměrně přesná aproximace sinusové vlny. To se samozřejmě projeví i na tvaru výstupků na povrchu tělesa, které již prakticky neobsahují ostré hrany. Všimněte si, že i malé množství hodnot uložených v mapě sklonů může vést k tvorbě poměrně složitého tvaru vlny:

CS24_early

slope_map {                  // mapa sklonu
    [0.00 <0.5, 1>]    // poloviční výška, sklon nahoru 45 stupňů
    [0.25 <1.0, 0>]    // maximální výška, nulový sklon
    [0.50 <0.5,-1>]    // poloviční výška, sklon dolů 45 stupňů
    [0.75 <0.0, 0>]    // minimální výška, nulový sklon
    [1.00 <0.5, 1>]    // poloviční výška, sklon nahoru 45 stupňů
} 
povray2310

Obrázek 10: Třetí demonstrační příklad po vykreslení POV-Rayem

Na závěr následuje výpis zdrojového kódu třetího demonstračního příkladu:

// ------------------------------------------------------------
// Třetí 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,
// velikost a směr modulačního vektoru je ovlivněm mapou sklonů.
//
// 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.40, 4.0, -4.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,    1.0, -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í
            slope_map {                  // mapa sklonů
                [0.00 <0.5, 1>]    // poloviční výška, sklon nahoru 45 stupňů
                [0.25 <1.0, 0>]    // maximální výška, nulový sklon
                [0.50 <0.5,-1>]    // poloviční výška, sklon dolů 45 stupňů
                [0.75 <0.0, 0>]    // minimální výška, nulový sklon
                [1.00 <0.5, 1>]    // poloviční výška, sklon nahoru 45 stupňů
            }
            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
// ------------------------------------------------------------ 

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.