Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
C/C++
Jak vyzrát na efekty 1.díl - Světla
13. března 2002, 00.00 | V tomto článku si ukážeme, jak naprogramovat jednoduché čočkové efekty, které vylepší náš 3D engine..
Tak jsem tu zase. Dnes Vás nebudu otravovat nějakými kolizemi, ale ukážeme si, jak udělat něco, co je opravdu na programu na první pohled vidět. Každý z Vás asi vidí o kolo každého světla záři. Pokud budeme mít dosti intenzivní zdroj světla, jakým je například Slunce, můžeme při jeho natáčení na kameru padnout na další zajímavý efekt a tím je jakýsi kruh okolo středu a série dalších kruhů a prstenců různých barev, které jsou rozmístěny na jedné přímce směrem od světla ke středu objektivu. Tyto efekty budeme souhrně nazývat čočkové, protože vznikají díky chybám čoček.
Co budeme potřebovat?
Nejdříve si musíme světlo umístit do prostoru a budeme s ním zacházet
jako se světlem bodovým(světlo se šíří v kuloplochách směrem
od středu).
|
Co znamená proměnná flags? Do ní uložíme parametry světla jako Glow,Start,Ring (ale to až dále). Do této proměnné zapisujeme pomocí funkce Add_Flag(flag). Tato funkce provede asi toto : flags=flags | flag; (přidá ji do seznamu). Proto doporučuji při inicializaci světla spustit funkci Clear_Flags(), která nastaví proměnnou flags na 0x00000 (0). Zjištění jestli je položka v seznamu je velice jednoduché if(flags & flag == 1)...je v seznamu.
Nadefinujme si tedy základní flagy :
#define LIGHT_FX_RING 0x00000001 //prstenec okolo středu
#define LIGHT_FX_STAR 0x00000010 //paprsky
#define LIGHT_FX_GLOW 0x00000100 // záře
#define LIGHT_FX_ASEC 0x00001000 //automatic secondaries
Záře
Teď jsme si tedy nadefinovali, jak bude vypadat základ našeho objektu SVĚTLO. Postupně budeme připisovat jednotlivé metody a proměnné. S takto definovaným světlem jsme již schopni vykreslit základní záři se středem v position[3](x,y,z), barvě glow_color a velikosti glow_size (jde samozřejmě o kružnici, tudíž o poloměr). Nejlepším řešením je si onu záři uložit jako bitmapu a do scénu ji následně plácat pomocí blendingu.
Druhé bitmapky si zatím nebudeme všímat, k ní se dostaneme později. Jelikož je bitmapa v odstínech šedi, umožňuje nám měnit libovolně její barvu pomocí příkazu glColor4fv(glow_color). Pochopitelně musíme nejdříve nastavit požadovanou barvu. Někteří z Vás si teď možná řeknou, že sice vykreslíme plošku v prostoru, která bude mít na sebe "naplácnutou" tuto texturu, ale jakmile se kamera otočí jiným směrem, otočí se i tato ploška. Jak zařídit, aby normála plošky byla stále orientována směrem ke kameře? Je to relativně jednoduché. Nadefinujme si matici4x4 float Matrix4x4[16]; Do ní můžeme nahrát MODEL_VIEW_MATRIX z OpenGL : glGetFloatv(GL_MODELVIEW_MATRIX,Matrix4x4); Když z této matice, která vyjadřuje umístění objektů v prostoru z pohledu kamery zbavíme posunutí(kamery) a transponujeme ji(prohodíme sloupce za řádky), dostaneme matici, která nám defakto "zruší" natočení kamery a ploška bude stále stejně orientována k vektoru, kterým se kamera kouká (tzn. stále to bude čtverec) :-)
|
Z důvodu úspory počítám tuto matici při posunutí kamery (C_CAMERA), která obsahuje model_view_matrix a transponovanou model_view_matri, dále svoje souřadnice. Pokud chcete celou její třídu, stáhněte si demo ze článku Jak vyzrát na kolize 3. Zde ji z úsporných důvodů znovu uvádět nebudu.
Teď jsme úspěšně matici transponovali a již s ní stačí pouze vynásobit současnou model_view_matrix, aby jsme zrušili ono otočení. Následně vykreslíme čtverec s texturou záře.
|
Na monitoru to pak vypadá asi takto : (světlo je nastaveno na
[1,1,1,1])
U paprsků postupujeme stejně jako u záře (nastavíme barvu, velikost), až na jeden menší detail. Pokud překryjeme nějakým objektem střed světla, budeme chtít, aby se paprsky nevykreslily, docílíme tím docela pěkného efektu při průletu objektu před světlem, paprsky zmizí, záře je stále vidět, pokud objekt nezakrývá celé světlo. K zjištění viditelnosti světla použijeme funkci OpenGL gluProject(), které zadáme souřadnice x,y,z, model_view_matrix, projekční matici a funkce nám vrátí x,y,z souřadnice v okně (z... je hloubka v okně, shodná se z-bufferem). Matice model_view_matrix, projection_matrix a parametry viewportu viewport načteme pomocí fce. glGetFloatv(). Objekt C_CAMERA obsahuje tyto informace po celou doby jednoho snímku, nemusí se proto nahrávat pro každé světlo, zdrojové kódy naleznete ve článku Jak vyzrát na kolize 3. (3D_camera.h/cpp a 3D_init.h/cpp)
|
Logicky nám do objektu C_CAMERA přibyla metoda Is_Center_Visible() a proměnné wnd_x,wnd_y,wnd_z (souřadnice světla v okně). Do metody Draw() můžeme nyní připsat pár řádek :
|
Na monitoru to pak vypadá asi takto : (paprsky maji barvu [0.9,0.8,0.0,1.0],
střed světla není překrytý)
Tady už nebudeme potřebovat texturu, protože použijeme opět jednu z funkcí OpenGL a tou je gluDrawDisk(). K tomu, aby se něco vykreslilo, musíme vytvořit GLUquadricObj * light pomocí funkce light = gluNewQuadric(); Všechna světla mohou tuto proměnnou sdílet, tak ji není třeba vkládat do třídy C:LIGHT. Přidáme tedy fnkci Draw_Ring();
|
V praxi to vypadá asi takto:
Toto byl asi nejlepší název, který mě napadl, například v 3D Studiu se mu říká Manual Secondaries. K vidění je převážně na filmech a to v případě, že kamera zabírá slunce(ale ne na každém filmu). Celý systém spočívá v tom, že vezmeme přímku, která prochází středem světla a středem kamery a na ni umístíme různě barevné kruhy a prstence. Aby jsme zabránili zmenšování kruhů v závislosti na vzdálenosti světla od kamery, přepneme v okamžiku vykreslování z perspektivy do ortografického zobrazení a budeme kreslit rovnou na "průmětnu" kamery. Aby byl celý systém variabilní, uložíme si informace o jednotlivých segmentech do libovolného pole, do kterého hodnoty načteme např. ze souboru.
|
Vim, že to asi vypadá dosti hnusně, ale je to velice jednoduché, stačí si to nakreslit. Do Draw() nám přirozeně přibude :
|
A co na to praxe?
No a to je vše! Zdrojové kódy naleznete ZDE
Těším se nashledanou u dalšího dílu, budeme se zabývat částicovými systémy.
Obsah seriálu (více o seriálu):
- Jak vyzrát na efekty 1.díl - Světla
- Jak vyzrát na efekty 2.díl - Částicové systémy
- Jak vyzrát na efekty 3.díl - stopy
- Jak vyzrát na efekty 4.díl - SkyBoxy, mlhoviny, atd.
- Jak vyzrát na efekty 5.díl - Lepší částice
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007