Hlavní navigace

Grafická knihovna OpenGL (18): vykreslování osvětlených těles

4. 11. 2003
Doba čtení: 7 minut

Sdílet

Tímto dílem seriálu o grafické knihovně OpenGL začínáme poměrně rozsáhlou část věnovanou nastavování a vykreslování osvětlených těles. Knihovna OpenGL totiž podporuje vykreslování plošek, které jsou vytvořeny z různých materiálů a mohou být osvětleny z několika světelných zdrojů různých typů. V dnešním dílu si popíšeme základní pojmy týkající se osvětlení a na příkladech si ukážeme, jakým způsobem lze jednoduše osvětlit těleso jedním zdrojem světla.

Materiály, osvětlení

Barva

V grafické knihovně OpenGL a mnoha dalších knihovnách i aplikacích je barva objektů a výsledných pixelů na obrazovce reprezentovaná trojicí barevných složek. Frekvence těchto barevných složek byla vybrána tak, aby co nejvíce korespondovala s frekvencí, na kterou jsou citlivé barvové senzory v lidském oku. Tyto tři základní barevné složky jsou: červená barva (Red – R), zelená barva (Green – G) a barva modrá (Blue – B). Vhodnou kombinací těchto barevných složek (o různé intenzitě) lze, poněkud překvapivě, vytvořit téměř jakoukoliv viditelnou barvu. Způsob reprezentace barvy pomocí tří barevných složek R, G a B nazývámebarvový model RGB (RGB Color Model, RGB Color Space)).

Tři základní barvy RGB jsou použity i u mnoha zobrazovacích zařízení, například u televizních obrazovek, CRT monitorů i LCD monitorů (aditivní barvy). Tyto typy zařízení přímo generují barevné světlo, ale například u tiskáren je použita jiná technologie, kdy barvy nanesené na papír světlo naopak pohlcují. Proto se u tiskáren používá doplňkových barev: modrozelená (cyan – C), fialová (magenta – M) a žlutá (yellow – Y) spolu s barvou černou (black).

Tímto tématem se však nebudeme podrobněji zabývat, nám bude stačit fakt, že v OpenGL se při osvětlování vždy pracuje s barevným modelem RGB, jehož tři základní barvové složky jsou zobrazeny na prvním obrázku. Jiné barevné modely lze využít pouze při texturování a práci s pixmapami.

Barvový model RGB - základní barevné složky a jejich kombinace
Obrázek 1: Barvový model RGB – základní barevné složky a jejich kombinace

Jakákoliv barva se tedy specifikuje trojicí hodnot, které reprezentují zastoupení jednotlivých barevných složek v barvovém modelu RGB. Tyto hodnoty mohou být zadány několika způsoby. Při specifikaci barev pro webové stránky nebo při ukládání barevných hodnot pixelů v různých grafických formátech rastrové grafiky (například BMP, PNG či TGA) je každá barevná složka uložena typicky v jednom bytu, tj. může nabývat hodnot 0..28-1, tj. 0..255 (v PNG je však možné použít i vícebitové hloubky). Celkový počet barev je tedy 2563, tedy cca 16 milionů.

V OpenGL se tento způsob reprezentace barevných složek příliš nepoužívá, protože by se při výpočtech osvětlení popř. blendingu do výsledných barev zanášela velká chyba. Místo toho je interně každá barevná složka reprezentována číslem uloženým v pohyblivé řádové čárce (floating point). Normou OpenGL přitom není specifikována ani přesnost ani rozsah této reprezentace, nicméně by měla odpovídat typu float podle IEEE. Každá barevná složka, ať již je zadána jakýmkoliv způsobem (například pomocí glColor4u()), je interně převedena do formátu pohyblivé řádové čárky. Až po výpočtu barvy jednotlivých vrcholů je tato hodnota zarovnána do rozsahu 0..1, je tedy možné zadávat libovolné hodnoty, a to i záporné (jak uvidíme dále, lze pomocí záporných barevných složek vytvořit „černé světlo“).

Osvětlovací model OpenGL

V OpenGL se pro výpočet barvy objektů ve scéně používá takzvaný Phongův osvětlovací model. Tento model se snaží co nejvíce zjednodušit fyzikální a optické vlastnosti reálného světla tak, aby výpočty osvětlení byly rychlé a aby se výsledný obrázek dostatečně blížil realitě. V Phongově osvětlovacím modelu se světlo, které na určitý objekt dopadá a následně se od něj odráží, rozkládá na tři světelné složky.

První složkou je takzvaná ambientní složka (ambient). Tato složka vyjadřuje okolní světlo, které není přímo vyzařováno ze žádných světelných zdrojů. Toto světlo vzniká tak, že se světlo z nějakého zdroje několikrát odrazí (například od stěn v místnosti), a není tedy jasně patrný směr, odkud přichází. V Phongově osvětlovacím modelu je toto světlo považováno za všesměrové, tj. osvětluje objekt ze všech směrů nezávisle na poloze a orientaci zdrojů světla. Ukázka tělesa osvětleného pouze ambientní složkou světla je zobrazena na druhém obrázku. Z tohoto obrázku je patrné, že nezávisle na 3D tvaru objektu se tento objekt jeví jako plošný, ztrácíme tedy prostorový vjem.

Těleso osvětlené pouze ambientní složkou světla
Obrázek 2: Těleso osvětlené pouze ambientní složkou světla

Druhou složkou světla je složka difúzní (diffuse). Tato světelná složka vyjadřuje světlo, které na povrch objektu dopadá z konkrétního světelného zdroje a od povrchu objektu se odráží do všech směrů se stejnou intenzitou. Pomocí difúzní složky lze tedy vytvářet matné materiály. V Phongově osvětlovacím modelu jsou výpočty difúzní složky světla upraveny tak, že výsledná barva difúzní složky je závislá pouze na vzájemné orientaci světelného zdroje a objektu. Poloha pozorovatele (kamery) nemá vliv na barvu ani intenzitu difúzní složky, čehož se dá využít například při urychlování vykreslovacích algoritmů. Ukázka tělesa, které je osvětleno pouze difúzní složkou světla, je zobrazena na třetím obrázku.

Těleso osvětlené pouze difúzní složkou světla
Obrázek 3: Těleso osvětlené pouze difúzní složkou světla

Poslední světelnou složkou použitou v Phongově osvětlovacím modelu jsou odlesky (specular). Odlesky vznikají ve chvíli, kdy na povrch tělesa dopadá paprsek ze zdroje světla a tento paprsek se od povrchu odráží podle známého zákona odrazu a lomu. Ve skutečnosti se paprsek nikdy neodrazí ideálně, vždy nastává určité rozptýlení. Phongův osvětlovací model tento fenomén modeluje tak, že se stanoví koeficient změny intenzity odraženého světla podle úhlu odklonu počítaného odraženého paprsku od paprsku ideálně odraženého. Vektory těchto dvou paprsků se vynásobí a výsledek se umocní zadaným koeficientem (bližší informace viz další díly). Ukázka tělesa se zobrazenými odlesky je zobrazena na čtvrtém obrázku.

Těleso s odlesky
Obrázek 4: Těleso s odlesky

Při vykreslování reálných těles se téměř nikdy nepoužívá pouze jedna světelná složka, vždy se jedná o jejich vzájemnou kombinaci. Na dalších třech obrázcích jsou vykreslena tělesa osvětlená některou kombinací světelných složek. Na pátém obrázku je kombinována ambientní a difúzní světelná složka, což je často používaná kombinace, protože výpočet obou světelných složek je poměrně rychlý (narozdíl od výpočtu odlesků, kde se musí provádět větší množství aritmetických operací). Na šestém obrázku je kombinace ambientní složky s odlesky a na sedmém obrázku jsou použity všechny tři světelné složky. Tento obrázek se také nejvíce blíží realitě.

Těleso osvětlené ambientní a difúzní složkou světla
Obrázek 5: Těleso osvětlené ambientní a difúzní složkou světla

Těleso osvětlené ambientní složkou světla s odlesky
Obrázek 6: Těleso osvětlené ambientní složkou světla s odlesky

Těleso osvětlené difúzní složkou světla s odlesky
Obrázek 7: Těleso osvětlené difúzní složkou světla s odlesky

Těleso osvětlené ambientní i difúzní složkou světla s odlesky
Obrázek 8: Těleso osvětlené ambientní i difúzní složkou světla s odlesky

V OpenGL se koeficienty světelných složek zadávají jak pro materiál, ze kterého je těleso vyrobeno, tak pro jednotlivé zdroje světla. Více informací o materiálech a zdrojích světla si řekneme v následujících dílech.

Světla v OpenGL

Při používání osvětlení v OpenGL se musí nejprve povolit výpočet osvětlení a poté povolit jednotlivé světelné zdroje, kterých může být až osm. Větší počet světelných zdrojů však může zpomalovat výpočty a tím i čas vykreslování celé scény. U každého světla můžeme nastavit jeho parametry, tj. polohu a koeficienty jednotlivých složek světla.

Globální povolení výpočtu osvětlení se provede zavoláním funkce glEnable(GL_LIG­HTING), opětovné zakázání potom příkazemglDisa­ble(GL_LIGHTIN­G). Jednotlivá světla lze zapínat a vypínat příkazy glEnable(GL_LIGHT?) a glDisable(GL_LIG­HT?). Za znak otazník se přitom doplní číslo světla, které je v rozsahu 0..7, ale některé implementace OpenGL podporují i více světel.

Vlastnosti světelných zdrojů se nastavují pomocí funkcí glLighti(), glLightiv(), glLightf() a glLightfv(). Tyto funkce se liší pouze typem předávaných parametrů. Bližší popis všech parametrů těchto funkcí a jejich vliv na světelný zdroj bude uveden v následujícím dílu, zde jsou uvedeny pouze pro pochopení demonstračních příkladů.

Materiály v OpenGL

V OpenGL se kromě parametrů světelných zdrojů musí také nastavovat optické vlastnosti materiálů, ze kterých jsou tělesa vytvořena. Pro tento účel se používají funkce glMateriali(), glMaterialiv(), glMaterialf() a glMaterialfv(). Důležité je, že se vlastnost materiálu může měnit pro přední a zadní stranu vykreslovaných polygonů.

Phongův osvětlovací model počítá difúzní světelnou složku a odlesky s využitím informací o normálách ve vrcholech povrchu tělesa. Pokud nejsou normály definovány přímo, lze je pomocí funkcí OpenGL dopočítat, ale tato operace je velmi časově náročná, proto je vždy výhodnější normály vypočítat ještě před vlastním vykreslováním.

V dnešních demonstračních příkladech je pomocí funkcí knihovny GLUT vykreslena čajová konvice (teapot), která byla ve své době jakýmsi symbolem trojrozměrné počítačové grafiky (dnes je to spíše známý bunny či Buddha, v plošné grafice je to IMHO stále Mandelbrotova množina).

Pokračování

V dalším dílu si podrobněji popíšeme příkazy použité v dnešních demonstračních příkladech a ukážeme si také, které informace jsou potřebné pro výpočet barvy v Phongově osvětlovacím modelu.

Demonstrační příklady

prvním demonstračním příkladu (HTML verze tohoto příkladu) je ukázáno vykreslení klasické „počítačové“ čajové konvičky (teapot) osvětlené ambientní složkou světla. Všimněte si ztráty vnímání prostoru při tomto osvětlení.

Ve druhém demonstračním příkladu (HTML verze tohoto příkladu) je ukázáno vykreslení stejného tělesa, které je nyní osvětleno pomocí difúzní světelné složky. U této složky není zadána barva, proto je použita barva implicitní. Vnímání prostoru je u tohoto typu osvětlení na dobré úrovni.

Ve třetím demonstračním příkladu (HTML verze tohoto příkladu) je oproti druhému příkladu pouze změněna barva difúzní světelné složky. Všimněte si způsobu předávání barvy, zde není možné použít předávání jednotlivých barevných složek, jako je tomu například u funkce glColor3f().

ict ve školství 24

Čtvrtý demonstrační příklad (HTML verze tohoto příkladu) kombinuje osvětlovací model s výpočtem mlhy, který jsme si popsali minule. Stiskem pravého tlačítka myši a jejím posuvem je možné objektem posouvat vpřed/vzad a sledovat jeho postupné stmívání se vzrůstající vzdáleností.

Pro majitele pomalejších linek je zde k dispozici celý článek i s přílohami.

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.