>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Textury na 3D polygony <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Zde musím poděkovat Robertu Schmidtovi (Robert@stud.unit.no), který napsal takový krátký pokec o jedné z mnoha metod mapování textur, kterou bych teď asi trochu přiblížil, neboť je jednoduchá a pochopitelná (ne že by ostatní nebyly)... Textury jsou vlastně malé (není pravidlo) bitmapy, které se "nalepí" na 3D polygon. Tento pak vypadá daleko realističtěji (viděli jste Dooma ? - když se rozhlédnete okolo, všude jsou textury), než pouhé stínování jednobarevných polygonů (představte si Dooma bez textur) ... Je libo obrázek ? Tady je ! No jak vidíte, snažil jsem se :) ... Ale z5 k obrázku - následuje komentář : pp - je vektor táhnoucí se z počátku souřadnic do bodu, který právě bb - je vektor vedoucí z počátku do jednoho z vrcholů polygonu ss - je vektor jdoucí z počátku do bodu na obrazovce, a je součástí vektoru pp. Tento vektor má tedy souřadnice [ssx,ssy,ssz] a souřadnice ssx resp. ssy by měly být v rozmezí 0-319 resp. 0-199. Z souřadnice je libovolná a odpovídá vzdálenosti obrazovky od oka (viz 3d transformace). uu - je jeden ze dvou vektorů ohraničujících polygon vv - to samý jako uu a*uu, b*vv - vyžadují trochu více vysvětlení - hodnoty a&b by měly být vždycky mezi 0 a 1 - pokud vede vektor pp do polygonu. Jsou to tedy relativní souřadnice bodu náležícího polygonu. No a úplné souřadnice získáme vynásobením velikostí vektoru (neboť jsme je vlastně předtím tímto vydělili - proč, ukážu za chvíli...) Hlavní myšlenkou tohoto algoritmu je najít pro každý vektor ss čísla a&b, která představují bod v polygonu. Dojdeme k tomu matematickou úvahou : Vektor pp je definován jako : pp = bb + a * uu + b * vv (vyplývá z obrázku) No a jak jste jistě postřehli, je vektor pp prodloužením vektoru ss. Lze tedy napsat : pp = k * ss Dosadíme-li do první rovnice získáme : k * ss = bb + a * uu + b * vv , Což se dá samozřejmě coby parametrická rovnice přímky rozepsat jako: k * ssx = bbx + a * uux + b * vvx k * ssy = bby + a * uuy + b * vvy k * ssz = bbz + a * uuz + b * vvz No a máme 3 rovnice a 3 neznámé, takže co nám chybí ? ....trying to computing ... Vzhledem k tomu, že jsem tvor strašně línej, nechal jsem to za sebe spočítat MathCad (neni úplně blbej, i když to tak na první pohled vypadá. Dnes mohu zodpovedne prohlasit, ze NEJLEPCI matyematickej program je MAPLE). Takže finální výsledky : (vvy*bbz-bby*vvz)*ssx + (vvz*bbx-bbz*vvx)*ssy + (vvx*bby-bbx*vvy)*ssz a = ------------------------------------------------------------------------ (uuy*vvz-vvy*uuz)*ssx + (uuz*vvx-vvz*uux)*ssy + (uux*vvy-vvx*uuy)*ssz (bby*uuz-uuy*bbz)*ssx + (bbz*uux-uuz*bbx)*ssy + (bbx*uuy-uux*bby)*ssz b = ------------------------------------------------------------------------- (uuy*vvz-vvy*uuz)*ssx + (uuz*vvx-vvz*uux)*ssy + (uux*vvy-vvx*uuy)*ssz Docela dobrý rovnice, ne ??? Abych neodběhl od tématu ... co teď s tím a&b ? No nic jednoduššího než je vynásobit velikostma textury (bitmapy), kterou máme někde v paměti schovanou. A vzhledem k tomu, že tyhle čísla jsou mezi 0 a 1, tak se nám tam ta bitmapa krásně nalepí. Takhle by to mohlo vypadat v programu : for y:=0 to 199 do for x:=0 to 319 do { výpočet a&b ; if (a>=0) and (a<1) and (b>=0) and (b<1) then putpixel(x,y,bitmapa[a* bmp_size, b*bmp_size]); } Tenhle příklad se ale hodí akorát tak na vyzkoušení, neboť není _vůbec_ optimalizován. Co by se na něm dalo vylepšit ? • nepočítat a&b pro všechny body na obrazovce, neboť ne všechny náleží polygonu (viz vyplňování polygonů) • všechno co se nemění dát do konstant a počítat mimo smyčku Nevýhoda této metody je to, že na jeden pixl připadá minimálně jedno dělené, což sice není katastrofa, ale v složitějších algoritmech nebo scénách to může brzdit. výheň