Textury, textury, mapujte seJan Petkov
Máte-li chuť postavit si vlastního Alien Breeda 3D, stačí když se naučíte
programovat (nejlépe v assembleru), rozlousknete tajemství trojrozměrného světa
(k tomu vám pomůže odborná literatura) a nakonec svůj svět obarvíte na
realistično pomocí mapování textur (a k tomu je určen následující článek). Výraz „mapování“ má málo společného s kartografií, pro naše účely postačí,
když si uvědomíme, že vyjadřuje přenesení realistického vzoru na holou, nějakým
způsobem v prostoru pootočenou stěnu. Podle autorů světového jména se nejedná o
nic složitého, v jejich příručkách jsem našel velmi jednoduchou funkci: Barva_Bodu = MapovacíFce(X,Y,Z) Není nic jednoduššího, Barvu Bodu hledáme, souřadnice bodu holé plochy
(X,Y,Z) známe, nezbývá než najít MapovacíFci. A tak jsem hledal a bloumal...
Chytré hlavy ve svých knihách moudře mlčí a z toho jsem odvodil jasný závěr, že
se jedná o tak primitivní záležitost, se kterou i odborníci odmítli ztrácet čas.
A ono ouha, postupně se mi začalo v hlavě rozednívat a nejenže při respektování
všech důležitých zákonů 3D světa (osvětlení, perspektivy,...) začala MapovacíFce
růst na složitosti, ale stala se tak pomalá, že bych musel čekat na PowerPC
desáté generace, abych si zobrazil okýnko 32 na 32. A tak nám nezbývá než
pokračovat ve vyšlapané linii starých programátorů, kdy musíme všechny zákony
přirozeného světa nějakým způsobem obelstít.
Nejdříve si ukážeme, jak u bitmapových objektů, které jsou v paměti uloženy jako
obdélníkové oblasti, úspěšně měnit velikost. Dejme tomu, že máme objekt, který
je 100 pixelů široký a 120 vysoký. Chceme-li jej 2 krát zvětšit, pak výsledek
bude asi zcela určitě mít rozměry 200x240. Jinými slovy, každý řádek v obrázky
zdvojíme a podobně zdvojíme i každý sloupec. Naopak, budeme-li žádáni aby
obrázek 2 krát zmenšil svou velikost na 50x60 pixelů, potom každý druhý řádek i
sloupec vypustíme. Algoritmy na tato kouzla nejsou těžké a oplývají vysokou
rychlostí.
Trošičku horší je to u obecné změny velikostí obrázku. Změníme velikost z
originálních 100x 120 na 150x30. Na pomoc si pozveme modifikaci DDA algoritmu.
Zavedeme si pojem „poměr změny“, který definuje vzoreček poměr změny = původní rozměr / cílový rozměr pro dvojnásobnou velikost: poměr změny = 200/100 = 2
pro poloviční velikost: poměr změny = 50/100 = 0.5 Ano správně tušíte, že zdvojení případně vynechání pixelu se řídí právě
poměrem změny. Takto se nám podařilo objevit skrytou zákonitost a můžeme se
pustit do obecného zvětšení.
Celý proces si osvětlíme na příkladu: chceme změnit rozměr jednoho řádku obrázku
z původních 100 pixelů na 150. Protože kreslíme řádek 150 pixelů široký, je
jasné, že celý vykreslovací cyklus musí proběhnout od 1 do 150 (FOR x=1 TO 150).
Pro každý pixel na novém řádku provedeme tento proces: zjistíme jaká barva mu
odpovídá v originálním řádku (barva = GET(INT(orig_x)) ) a touto barvou obarvíme
pixel v novém řádku (PLOT(x,barva)). Abychom získali správnou barvu, musíme
průběžně procházet i původní řádek (orig_x = orig_x + pomer).
Celý proces se dá přirovnat k situaci, kdy máte pomalejší auto na kratší úsek a
rychlejší auto na delší úsek, obě auta vyrazí najednou a potřebujete, aby byly
na konci úseků současně. orig_x = 1.0
pomer = 100/150
FOR x=1 TO 150
barva = GET(INT(orig x))
PLOT(x,barva)
orig_x = orig_x + pomer
ENDFOR Věřte mi nebo ne, s tímto algoritmem jste už schopni sestavit hru typu
Wolfenstein 3D (kolmé stěny pokryté texturou, podlaha a strop jsou holé). Kolmé
stěny mají totiž tu výhodu, že zůstávají při otočení kolem svislé osy pořád
kolmé, jinými slovy svislý sloupec stěny zůstane i po otočení pořád svislým
sloupcem třebaže jinak vysokým, ale změnit výšku umíme výše uvedeným algoritmem.
Pokusím se texturování kolmých stěn shrnout: tyto stěny se vyplňují po
sloupcích, může se maximálně měnit počet a výška sloupců ve stěně, ale to není
nic s čím bychom se nebyli schopni poprat. Zkuste si to nakreslit a bude vám to
jasné. Algoritmus pro texturování kolmých stěn má tuto základní podobu: FOR x=1 TO šířka_stěny
zjisti_výšku_sloupce_X
orig_y = 1.0
pomer = orig_výška/výška_sloupce
FOR y=1 TO výška sloupce
barva = GET(INT(orig_y))
PLOT(y,barva)
orig_y = orig_y + pomer
ENDFOR
ENDFOR Nyní se dostávám k velkému oříšku, není mi jasné, jak vám mám bez tužky a
papíru vysvětlit mapování textur na obecně pootočenou stěnu, pokusím se.
Zvětšování obdélníkových objektů stejně jako mapovaní textur na kolmé stěny mají
jednu společnou vlastnost - buď všechny nebo alespoň dvě protilehlé strany jsou
k prostoru vodorovné nebo kolmé (tedy nějakým způsobem svírají s prostorem pravý
úhel). To je pro mapo vání nesmírně výhodné, protože textury v paměti jsou
uloženy rovněž v pomyslných pravoúhlých oblastech. Například sloupec z paměti
mapuji opět na sloupec na obrazovce a přitom jenom měním jeho délku.
Nyní ovšem přichází problém, kdy řádek či sloupec v paměti odpovídá šikmé úsečce
na obrazovce, což je nepříjemné. A protože zkušenost praví, že při takovém směru
mapování vznikají chyby, musíme směr obrátit, tedy řádek (sloupec) na obrazovce
odpovídá šikmému průchodu texturou v paměti, což je ještě nepříjemnější. Nese to
s sebou tu skutečnost, že budeme muset DDA algoritmus aplikovat nejen na délku
úsečky, ale i na průchod texturou (tedy změnu X a Y pozice). Další kroky jsou
ovšem textovou formou nevysvětlitelné, tedy alespoň pro mé skromné vyjadřovací
schopnosti, postačí když chviličku podumáte s tužkou v ruce a bude vám to vše
nad slunce jasné. Ještě malá poznámka na závěr:
Jak už jsem se zmínil v úvodu nerespektuje tento typ mapování textur
základní zákony realistického prostoru (nyní mám na mysli především
perspektivu). Proto je nanejvýš vhodné, aby ani vzory textur ani holé stěny
neměly příliš velké rozměry. Mohli byste se dočkat psychedelických zážitků. Vytlačiť článok
Pozn.: články boli naskenované ako text a preto obsahujú aj zopár chýb. Taktiež neručíme za zdrojové kódy (Asm, C, Arexx, AmigaGuide, Html) a odkazy na web. Dúfame, že napriek tomu vám táto databáza dobre poslúži.
Žiadna časť nesmie byť reprodukovaná alebo inak šírená bez písomného povolenia vydavatela © ATLANTIDA Publishing
none
|