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.

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).
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á.

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:

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
}
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
// ------------------------------------------------------------
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
// ------------------------------------------------------------
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ě).
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ňů
}
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:
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ňů
}
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
// ------------------------------------------------------------