Tietokonegrafiikka / perusteet T-111.300/301 4 ov / 2 ov Peruskäsitteitä Z-buffer Syvyyslajittelu Juovalajittelu Rekursiivinen aluejako Piiloviivat Sisältö Luento 6: Piilopinnat Marko Myllymaa 09/03 Piilopinnat / 1 Piilopinnat / 2 Peruskäsitteitä piiloviiva-algoritmi etsii viivakuvasta peittävien pintojen taakse jäävät viivojen osat ja poistaa ne tai piirtää ne vaimennettuina, esim. katkoviivoina. piilo-algoritmi piirtää sävytetystä kuvasta vain katselupisteeseen näkyvät pintojen osat ja eliminoi peittyvät pinnat tai piirtää ne vaimennettuina, jos peittävät pinnat ovat läpikuultavia. Algoritmi voi toteutua rasterikuvan juovakonversion yhteydessä (kuva-avaruudessa) tai olla erillinen vaihe, joka ainoastaan jakaa mallin (joko 2-ulotteisena projektiona tai 3-ulotteisessa objekti-avaruudessa) näkyviin ja peittyviin osiin. Peruskäsitteet (jatkuu) Kaikki menetelmät toteuttavat tavalla tai toisella pistekohtaisen syvyysvertailun (vain lähin piste piirretään). Lajittelemalla kuvamateriaalia voidaan hyödyntää koherenssia ja vähentää vertailujen määrää (piirretään saman vertailun tuloksena laajempia alueita kuin pikseleitä). Seuraavissa algoritmeissa oletetaan käsiteltävän mallin koostuvan tasomaisista monikulmioista (mallit usein vaikkakaan eivät aina sulkeutuvia monitahokaspintoja). Muun tyyppiset mallit voidaan joko muuntaa monikulmiomalleiksi tai käyttää ko. malleille spesifisiä algoritmeja. Piilopinnat / 3 Piilopinnat / 4 Yksinkertaisia tapauksia pelkkiä viivoja sisältävälle ns. rautalankamallille ei aitoa piiloviiva-algoritmia voi toteuttaa, koska mallissa ei ole peittäviä pintoja.tämä voidaan osittain korjata ns. halo-algoritmilla, jossa kullekin viivalle oletetaan sopivan levyinen, taemmas jääviä viivoja peittävä "sädekehä". Sopivalla leveyden valinnalla saadaan varsin havainnollisia kuvia. Yksinkertaiset tapaukset jatkuu n z e > 0 takana n z e < 0 näkyvissä n z e = 0 siluettitaho (näkyy vain viivana) z Nz > 0 Nz < 0 xy konveksin monitahokkaan kukin taho on aina kokonaan näkyvä tai näkymätön. Takapinnalla piilossa oleva taho voidaan tunnistaa vertaamalla sen normaalivektorin n suuntaa (sopimuksen mukaan aina monitahokkaan pinnasta ulospäin) katselusuuntaan osoittavaan vektoriin z e. Huom.1 tavallisesti katselusuunta on z-akseli, jolloin riittää tarkastella normaalin z-komponentin n z etumerkkiä. Huom.2 takatahojen poisto on hyödyllinen esikäsittelyvaihe muille algoritmeille (vähentää tahojen määrän n. puoleen). Huom.3 konveksille monitahokasmallille riittävä, konkaaville ei Piilopinnat / 5 Piilopinnat / 6 1
Syvyyspuskuri (Z-buffer) Piirrettäessä kuvaa merkitään jatkuvasti kuhunkin pikseliin muistiin sekä toistaiseksi lähimmän siihen osuneen kuvapisteen väri että sen etäisyys (z-arvo) katselupisteestä. Helppo toteuttaa: 1. Alustus: for each pixel do begin color[x,y] := background_color; depth[x,y] := max_depth end Z-buffer (jatkuu) z-arvo normalisoidussa katselukoordinaateissa (clipping planes) Vaatii muistia Esim. 340 x 512 pikselin kuvalle, jossa 256 väriä ja syvyysarvoa (väri-indeksi ja z-arvo ilmaistu 8 bitillä), tarvitaan 340 kilotavua. Vastaavasti 1024 x 1024 pikselin kuva, jossa kullekin pikselille on varattu 32-bitin sana (8 bittiä z-arvolle ja kullekin RGB-päävärille), vaatii 4 megatavua. Antialiasointi ja läpinäkyvyys vaativat erikoisjärjestelyjä, esim. ns. A-puskuria 2. Joka objektille (mielivaltaisessa järjestyksessä!) projisointi ja juovamuunnos, minkä yhteydessä kunkin pikselin kohdalla: if z < depth[x,y] then begin color[x,y] := object_color ; depth[x,y] := z end Piilopinnat / 7 Piilopinnat / 8 Syvyyslajittelu (maalarin algoritmi) Lajitellaan pinnat syvyyden (prioriteetin) mukaan ja maalataan ne päällekkäin järjestyksessä takaa eteen, jolloin taaemmat aina peittyvät. Helppo, jos prioriteetit ennalta määrätty muuten periaatteessa vertailtava jokaista a kaikkiin muihin pintoihin (kompleksisuus N 2 ) ja määrättävä prioriteetti syvyyden tai peittävyyden perusteella. Vertailu kannattaa tehdä monessa vaiheessa ja hyödyntää objektien ympäryslaatikoita. Kaksivaiheinen algoritmi: aluksi järjestetään kaikki objektit prioriteettilistaksi suurimman etäisyytensä Z max mukaan. sitten käydään lista läpi kauimmasta objektista (S) alkaen verraten sitä muihin listassa. Jos S ei peitä mitään muuta a, se piirretään näkyviin ja poistetaan listasta, muussa tapauksessa vaihdetaan S ja sen peittämä Q keskenään. Piilopinnat / 9 Vertailussa käydään läpi seuraavat testit (tässä järjestyksessä); jos yksikin toteutuu, ei S voi peittää Q:ta, jolloin järjestys on oikea eikä muita testejä tarvita: 1. ympäryslaatikoiden päällekkäisyys z-suunnassa: jos Z min (S) > Z max (Q), niin S on taempana. 2. ympäryslaatikoiden päällekkäisyys xy-suunnissa: jos X min (S) > X max (Q) tai X min (Q) > X max (S), niin S ei voi peittää Q:ta (syvyydestä riippumatta). z Vastaava testi tehdään myös Y-suunnassa. xy x Piilopinnat / 10 y 3. päällekkäisyys monikulmion sisältävän tason suhteen: a) jos kaikki S:n kulmapisteet Q:n tason takana, tai b) jos kaikki Q:n kulmapisteet S:n tason edessä, niin S ei peitä Q:ta. 4. jos S:n ja Q:n projektioiden (kuvatasolla 2-ulotteisia monikulmioita) leikkaus on tyhjä, ei S voi peittää Q:ta. Esimerkki pinnoista, joiden järjestys joudutaan vaihtamaan Z S' S X 5. ellei mikään eo. testeistä tuota tulosta, valitaan jokin piste ed. kohdassa todetusta päällekkäisestä alueesta. Tämän kummallekin tasolle laskettu etäisyys määrää lopullisen järjestyksen. Piilopinnat / 11 Piilopinnat / 12 2
Huom.1 syvyyslajittelu voi vaatia useampiakin vaihtoja, joten järjestystä listassa kerran vaihtaneet pinnat on merkittävä ja toistettava vertailut vielä näiden suhteen. Z Huom.2 joskus järjestäminen ei onnistu lainkaan (algoritmi joutuu ikuiseen silmukkaan). Tällainen ns. syklinen peittävyys ratkaistaan pilkkomalla pintoja osiin, esim. jakamalla yksi toisen tasolla. Sama joudutaan tekemään, jos pinnat lävistävät toisensa. A B C X ACB ->? ->? Syvyyslajittelu toimii objektiavaruudessa, vaikka vertailu perustuukin kuva-avaruuden koordinaatistoon. Piilopinnat / 13 Piilopinnat / 14 Juovalajittelu (XYP-lajittelu) Muunnetaan monikulmiot pyyhkäisyjuoviksi tavalliseen tapaan lajitellen ensin monikulmiot ja niiden reunajanat y-suunnassa ja sitten kullekin juovalle jäävät monikulmion osat (janat) x- suunnassa. Saadut janat lajitellaan vielä syvyytensä (P) mukaan ja valitaan kuhunkin pikseliin lähimmän janan väri. Tässä siis syvyyslajittelu tehdään kokonaisten 2-ulotteisten monikulmioiden sijasta niiden 1-ulotteisille viipaleille pyyhkäisyjuovilla. Muuten suoritettavat vertailut ovat vastaavanlaisia: kulmiot järjestetään ylimmän kohtansa (Y max ) mukaan. kunkin monikulmion reunajanat järjestetään Y:n suhteen. kullakin juovalla Y s päivitetään aktiivisten monikulmioiden (so. niiden, joille Y min < Y s < Y max ) listaa, ja näistä kustakin vielä aktiivisten reunojen listaa. leikkaamalla pyyhkäisyjuovaa aktiivisilla reunoilla saadaan janoja, jotka järjestetään X-suunnassa. y scan line peittävyys pyyhkäisyjuovalle saatujen janojen kesken ratkaistaan samalla kun viivoja piirretään: A x B S1 D jos janat erillisiä X-suunnassa, ei vertailua tarvita. H E C S2 F Piilopinnat / 15 Piilopinnat / 16 päällekkäisten janojen suhteet saadaan vertaamalla niiden etäisyyksiä kussakin janojen päätepisteessä. jos kunkin osajanan päissä etäisyysssuhteet ovat samat voidaan ko. osajana piirtää. Jos suhteet vastakkaiset (janan päätepisteet eripuolilla toisen monikulmion tasoa), niin pinnat lävistävät toisensa, jolloin leikkauspisteessä osajanat vielä jaetaan ja piirretään erikseen. Huom. laskenta inkrementaalisesti, myös z-koordinaatti mukana: monikulmion tasoyhtälö: Ax + By + Cz + D = 0 > z = (Ax + By + D) / C z(x+1) = z(x) A/C z(y+1) = z(y) B/C kuten Z-puskurillekin, aliasoituminen ongelmana ratkaisu vastaavanlainen (esim. A-puskuri). Piilopinnat / 17 Piilopinnat / 18 3
Rekursiivinen aluejako 1) Tarkastellaan aluksi koko kuvaruutua yhtenä alueena kuva-alueen ja monikulmion mahdolliset suhteet 2) Jos peittävyys on triviaalisti ratkaistavissa, voidaan kuva piirtää sellaisenaan. 3) Muussa tapauksessa jaetaan kuvaruutu pienempiin osiin (esim. neljänneksiin), joissa sama tarkastelu toistetaan. 4) Tarvittaessa jatketaan osiinjakoa rekursiivisesti jopa yhden pikselin kokoisiin alueisiin, kunnes kunkin alueen sisältämä kuva on piirretty. ympäröivä leikkaava sisältyvä ulkopuolinen ympäryslaatikon avulla saadaan helposti selville, onko monikulmio kokonaan sisällä tai varmasti ulkona. Muuten käytetään leikkausalgoritmia hyväksi (Jos monikulmion reuna leikkaa ruudun reunaa, on tuloksena osittainen peittävyys, muuten monikulmio on kokonaan ulkona tai ympäröi ruutua.) Piilopinnat / 19 Piilopinnat / 20 jos ruudun sisällä on enintään yksi monikulmio tai sen osa, on tilanne triviaali, ja ruutu piirretään. jos joku monikulmio P ympäröi ruutua, niin kaikki sitä kauempana olevat (ne, joiden Z min > Z max (P) ruudun sisällä tai nurkissa laskettuna), peittyvät joka tapauksessa ja voidaan hylätä. muussa tapauksessa ruutu jaetaan osiin, samalla siirtäen jo tunnettua informaatiota ( = lista kiinnostavista objekteista) eteenpäin: vain ruutua leikanneita objekteja tutkitaan ruudun osissa - ruutua ympäröivä monikulmio ympäröi myös kaikkia ruudun osia helpoimmin osiinjako tapahtuu binäärisesti (aina neljänneksiin), mutta voidaan tehdä myös esim. jonkin monikulmion nurkan kohdalta, jolloin osiinjakoja saatetaan tarvita vähemmän. Esim. Piilopinnat / 21 Piilopinnat / 22 octree Muut kuin monikulmiomaailmat kaarevat pinnat Piiloviiva-algoritmit Kaikki piilo-algoritmit voidaan muuntaa myös piiloviivoja käsitteleviksi. Esimerkiksi maalarin algoritmissa voidaan piirtää kunkin näkyvissä olevan objektin reunat erottuvalla värillä ja sisäosa taustavärillä (jolloin se peittää taempana olevat reunat). Varsinaiset piiloviiva-algoritmit toimivat objekti-avaruudessa, ts. tuottavat tuloksena ne osat alkuperäisistä viivoista, jotka näkyvät. Periaatteessa joudutaan tutkimaan kunkin viivan näkyvyys vertaamalla sitä kaikkiin pintoihin, ja katkaisemaan viiva, jos vain osa siitä näkyy. Huom. malli voi sisältää myös sellaisia viivoja, jotka eivät ol e minkään pinnan reunoja, vaan irrallaan avaruudessa. Piilopinnat / 23 Piilopinnat / 24 4
Piiloviivat (jatkuu) Eräs alkuperäinen piiloviiva-algoritmi perustuu siihen, että viivat muodostavat verkkoja, joissa kulkien voidaan näkyvyys ratkaista inkrementaalisesti: haetaan aloituspiste, jolle selvitetään ns. peittyvyysindeksi, so. sitä peittävien pintojen lukumäärä. seurataan ratkaistusta pisteestä lähtevää viivaa ja haetaan pisteet, joissa seurattava viiva leikkaa toista viivaa. verrataan leikkauspisteessä viivojen etäisyyksiä: jos tutkittava on taempana, niin sen peittyvyysindeksiä kasvatetaan tai vähennetään yhdellä sen mukaan, meneekö viiva pinnan alle vai tulee sieltä pois. viivoja seurattaessa piirretään samalla näkyviin ne viivan osat, joiden peittyvyysindeksi on nolla. Syvyyslajittelu on tehostava apukeino myös yllä kuvatussa algoritmissa, samoin rekursiivinen aluejako tai XY-lajittelu. Piilopinnat / 25 5