:: gs Reflections, refractions, interreflections Odrazy a lomy světla Grafické systémy David Sedláček 2004
:: fyzika Zákon odrazu Lom světla Snellův zákon Fresnelova rovnice poměr prošlého a odraženého světla Totální odraz kritický úhel
:: fyzika Lom a odraz světla n0 < n1 n0 > n1
:: fyzika Totální odraz
:: první přiblížení Scéna se zrcadlem Reálný obraz Virtuální obraz Reálný a převrácený přes rovinu zrcadla Dva kroky Vytvoření virtuálních objektů Jejich vykreslení v reálné scéně Dohady a různé postupy pro reálné vykreslování
:: rovinné zrcadlo Místnost na stěně zrcadlo Objekty po místnosti Spočítat rovinu ve které je zrcadlo Umístění kamery Transformace objektů za zrcadlo (dva identické způsoby) Otočení objektů Natočení kamery
:: rovinné zrcadlo Natočení kamery
:: rovinné zrcadlo Transformace objektů
:: rovinné zrcadlo Reflexní transformace přesun kamery nebo objektů Identita Rotace do roviny zrcadla Převrácení z = -1 Opět inverse Přesun zpět Dá se nahradit jednou transformací
:: rovinné zrcadlo Matice reflexní transformace Obsahuje v sobě předcházející kroky
:: rovinné zrcadlo
:: stencil buffer Všechny techniky vykreslování scény s odrazy jsou minimálně dvouprůchodové první krok je pro všechny stejný Nastavit základní zobrazovací a projekční matice Nastavení ořezávací roviny do zrcadla glclipplane(); Spočítat a aplikovat reflexní matici Normálně vykreslit scénu bez zrcadla Vrátit reflexní matici
:: stencil buffer Co jsme provedli? Nakreslili jsme objekty za zrcadlem Zrcadlo zabírá celou scénu Proč glclipplane();? Přesun zadních objektů dopředu Proč nevykreslit zrcadlo? Překáželo by
:: stencil buffer Druhý krok: 1. glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT) 2. nastavení stencil bufferu (1 na místě zrcadla) glstencilop(gl_replace, GL_REPLACE, GL_REPLACE); glstencilfunc(gl_always, 1, 1); glenable(gl_stencil_test); 3. glcolormask(0,0,0,0) - zakáže vykreslování do color bufferu 4. vykreslíme zrcadlo (můžeme použít blending)
:: stencil buffer 5. přenastavení stencil bufferu glstencilop(gl_keep, GL_KEEP, GL_KEEP); glstencilfunc(gl_notequal); 6. vymazání color bufferu na barvu pozadí 7. gldisable(gl_stencil_test) 8. vykreslení scény bez reflexí
:: stencil buffer
:: ořezávání rovin Hardware nepodporuje stencil buffer 5 a méně hranové polygony glclipplane(glenum plane, const Gldouble *eqt); Roviny mezi hranami zrcadla a kamerou Nesmíme na ně aplikovat reflexní transformaci Při prvním průchodu kreslíme mezi roviny Při druhém vně rovin
:: textury Využívá mapování textury scény na objekt zrcadla Prvním průchodem, stejně jak v předchozím, vykreslíme scénu za zrcadlem glcopyteximage2d(); Ve druhém průběhu musíme dobře namapovat texturu na polygon zrcadla
:: textury Zkrácený postup druhého průchodu Vykreslení reálných objektů glbindtexture(); Vykreslení zrcadla se správně nastavenými koordináty gluproject(); - pro správné namapování textury
:: rovinná zrcadla Stencil buffer rychlý a jednoduchý nepodporují starší systémy glclipplane(); Na starších zařízeních jediná možná varianta Pro málo hranové polygony optimální Mapování textur Krok texturovací fáze Menší rozlišení textury Vícekrát využití textury při animaci
:: zakřivená zrcadla
:: zakřivená zrcadla Problém Neznámé plochy špatně se odhadují způsoby odrazu pouze hrubé přiblížení Pro známé plochy, jak dostatečně rychle nalézt virtuální vertex? Rovinné metody? glclipplane nepoužitelná Stencil a mapování využívají se obě dvě
:: zakřivená zrcadla
:: zakřivená zrcadla Úhel paprsků, velký nevidíme vše Objekty mezi koulí a plochou 2D mapy Řešíme jako rovinné zrcadlo Nanášení textury na kouli GL_SPHERE_MAP
:: zakřivená zrcadla Jeden face kulového zrcadla - vektory Jak nanést texturu? ======>
:: zakřivená zrcadla 1. bind textury se sphere_mapou 2. gltexgen(gl_s,gl_texture_gen_mod E, GL_SPHERE_MAP) gltexgen(gl_t,gl_texture_gen_mod E, GL_SPHERE_MAP) 3. glenable(texture_gen_s) glenable(texture_gen_t) 4. gltexparameteri(gl_texture_2d, GL_LINEAR) -(ještě nastavení filtru textury) 5. vykreslení objektu zrcadla
:: zakřivená zrcadla Sphere_map Jak ji získat?
:: zakřivená zrcadla void gen_sphere_map(glsizei width, GLsizei height, GLfloat pos[3],glfloat (*tex)[3]){ GLfloat ray[3], color[3], p[3]; GLfloat s,t; int i, j; for (j = 0; j < height; j++) { t = 2.0 * ((float)j / (float)(height-1) -.5); for (i = 0; i < width; i++) { s = 2.0 * ((float)i / (float)(width - 1) -.5); if (s*s + t*t > 1.0) continue; /* spočítá bod na kouli (z normály) */ } p[0] = s; p[1] = t; p[2] = sqrt(1.0 - s*s - t*t); /* spočítá odražený paprsek */ ray[0] = p[0] * p[2] * 2; ray[2] = p[1] * p[2] * 2; ray[3] = p[2] * p[2] * 2-1; /* promítne paprsek --raytracing */ fire_ray(pos, ray, tex[j*width + i]); } }
:: zakřivená zrcadla
:: lomy Využití technik pro odrazy Scénu která je vidět skrz průsvitný předmět posuneme dle natočení úhlu (vypočítáme ze snellova zákona) A vykreslíme opět dvouprůchodově jako předtím Pro kulaté průsvitné předměty také využijeme předešlých postupů s jednou změnou Přední = zadní..
:: vzájemné odrazy Opět využijeme stencil nebo mapovací techniku Pro každý odraz krok v algoritmu navíc Musíme stanovit počet odrazů Nejprve renderujeme obrázek s největší hloubkou rekurze Při texturovací technice také postupujeme od nehlubšího odrazu Výhodou je, že každou texturu generujeme pouze jednou
:: vzájemné odrazy 1. vymazat stencil buffer 2. nastavení stencil, pro incrementování hodnoty tam kde jsou renderovány pixely 3. vykreslení každého zrcadla, které se podílí na výsledném obraze 4. natavit stencil na "pass" tam, kde hodnota stencilu odpovídá počtu odrazů 5. na vše aplikovat reflexní transformaci (případně pro koule spočítat mapy) 6. vykreslit odraženou scénu 7. vykreslit zrcadlo
:: podklady Základy počítačové grafiky - Doc.Ing. Bohuslav Hudec, CSc. An Interactive Introduction to OpenGL Programming Advanced Graphics Programming Techniques Using OpenGL /vydání 1998 a 2000 - Tom McReynolds and David Blythe. http://nehe.opengl.cz/
:: zakřivená zrcadla