Korkeuskartat Maaston muotojen generointi ja visualisointi Markku Mielityinen 8..00 Reaalimaailman jatkuva korkeusinformaatio joudutaan tietokoneissa kuvaamaan diskreeteillä korkeuspisteillä. Yleisin tallennusmuoto on käyttää neliön muotoista matriisia, jossa matriisin alkiot kuvaavat vastaavan ruudukon korkeuksia. Matriisissa sijaitsevat pienet arvot kuvaavat matalikkoja ja suuret arvot korkeita kohtia. Copyright Markku Mielityinen 00 Harmaasävykartat Spectral Syntetis Noise 1 Matriiseina tallennettavat korkeuskartat kasvavat usein varsin suuriksi. Korkeusinformaatio voidaan tallentaa esimerkiksi välillä [0,55], josta se muunnetaan sopivalla kertoimella vastaamaan piirrettävän maailman mittasuhteita. Tummat pisteet edustavat matalia ja vaaleat korkeita kohtia. Tällä tavalla kuvatut kartat voidaan tallentaa käyttäen harmaasävybittikarttoja. Standardien tiedostoformaattien käytöllä saavutetaan monia etuja. Kartan tallennuksessa voidaan käyttää tiedoston tukemaa pakkausalgoritmia, jolloin informaatio saadaan tiivistettyä pienempään tilaan. Lisäksi tiedostoja voidaan tuottaa ja käsitellä standardeilla työkaluilla. Spektri synteesi funktiot muodostavat mallin, jossa ei esiinny helposti havaittavissa olevaa toistuvuutta. Spektri synteesiä käytetään esimerkiksi säteenseurantaan perustuvissa piirtosovelluksissa erilaisten tekstuurien generointiin. Jos satunnaislukugeneraattorin siemen voidaan asettaa tapauskohtaisesti uudelleen, voidaan tarvittavat pinnat luoda ajonaikaisesti, eikä muistia kuluttavaan matriisiesitykseen ole välttämätöntä tarvetta. Korkeusinformaation luonti suoritetaan summaamalla yhteen kerroksia. Jokainen taso luodaan satunnaisgeneraattorilla, jonka jälkeen sen luonnollisuutta parannetaan käyttämällä tasoittavaa algoritmia. Kerroksien generoinnissa käytetään parametreina aallon pituutta ja korkeutta. Varioimalla näitä parametreja eri tasojen välillä saavutetaan luonnollisen näköisiä maastopintoja. Tasojen määrää kasvattamalla lisääntyy samalla luotavan pinnan sisältämien detaljien määrä. Käytännössä jo viidellä kerroksella saavutetaan useimpiin tarkoituksiin riittävä lopputulos. Copyright Markku Mielityinen 00 3 Copyright Markku Mielityinen 00 4 Spectral Syntetis Noise Spectral Syntetis Noise 3 1 taso 3 tasoa 5 tasoa 50 tasoa Copyright Markku Mielityinen 00 5 void fracsynthpass( float *hbuf, float freq, float zscale, int xres, // interpolate all vertical lines int zres ) for( x=0;x < xres;x++ ) { { int I, x, z; zk = 0; float *val; knots = zknots; int max; // build knot list float dfx, dfz, *zknots, *knots; for( i=0;i < max;i++ ) { float xk, zk, *hlist, *buf; knots[i] = hlist[i*xres+x]; // how many to generate (need 4 extra for smooth d spline interpolation) max = freq + ; for( z=0;z < zres;z++ ) { // delta x and z - pixels per spline segment buf[z*xres+x] = spline( zk/dfz, 4, knots ) * zscale; dfx = xres / (freq-1); zk += 1; dfz = zres / (freq-1); // the generated values - to be equally spread across buf if( zk >= dfz ) { val = (float*)calloc( sizeof(float)*max*max, 1 ); zk -= dfz; // intermediately calculated spline knots (for knots++; zknots = (float*)calloc( sizeof(float)*max, 1 ); // horizontal lines through knots hlist = (float*)calloc( sizeof(float)*max*xres, 1 ); // local buffer - to be added to hbuf buf = (float*)calloc( sizeof(float)*xres*zres, 1 ); // update hbuf // start at -dfx, -dfz - generate knots for( z=0;z < zres;z++ ) for( z=0; z < max; z++ ) { for( x=0;x < xres;x++ ) for( x=0;x < max;x++ ) { hbuf[z*xres+x] += buf[z*xres+x]; val[z*max+x] = SRANDOM; free( val ); free( buf ); // interpolate horizontal lines through knots free( hlist ); for( i=0;i < max;i++ ) { free( zknots ); knots = &val[i*max]; xk = 0; for( x=0;x < xres;x++ ) { hlist[i*xres+x] = spline( xk/dfx, 4, knots ); xk += 1; if( xk >= dfx ) { xk -= dfx; knots++; Copyright Markku Mielityinen 00 6 Copyright Markku Mielityinen 00 1
The Fault Algorithm 1 The Fault Algorithm Fault-algoritmi perustuu Fourier-muunnoksen tapaan yksinkertaisten komponenttien lisäämiseen johonkin tiettyyn nollatasoon. Jotta maaston pinnassa ei esiintyisi selvästi havaittavaa toistuvuutta, on iteraatiokierroksia suoritettava käytettyjen komponenttien luonteesta riippuen satoja, jopa tuhansia. Jokaisessa iteraatiovaiheessa avaruus jaetaan kahtia. Käytetyn komponenttifunktion origo sijoitetaan jakavalle suoralle ja funktion etenemissuusta asetetaan jakosuoran normaalin suuntaiseksi. Kynnysfunktio kasvattaa ruudukossa jakoviivan positiivisella puolella olevia korkeuksia d:llä ja vähentää jakoviivan negatiivisella puolella olevia korkeuksia d:llä. x < 0 H ( x) = d x 0 H ( x) = d Palikkamaisesta rakenteesta johtuen iteraatiokierroksia tarvitaan runsaasti. Copyright Markku Mielityinen 00 7 Copyright Markku Mielityinen 00 8 The Fault Algorithm 3 The Fault Algorithm 4 Pehmennetty kynnysfunktio vaihtaa kynnysfunktion terävät kulmat ympyrän kaariksi pehmentäen näin aikaansaatua muutosta. Kytkemällä kaksi pehmennettyä kynnysfunktiota vastakkain saadaan aikaan maski, joka tuottaa kumpujonoja. Pehmennetyn kynnysfunktion tilalla voidaan käyttää esimerkiksi logistista sigmoidia. Copyright Markku Mielityinen 00 9 Copyright Markku Mielityinen 00 10 The Fault Algorithm 5 The Fault Algorithm 6 1 iteraatio 16 iteraatiota iteraatiota 100 iteraatiota 3 iteraatiota 400 iteraatiota Copyright Markku Mielityinen 00 11 Copyright Markku Mielityinen 00 1 Copyright Markku Mielityinen 00
The Fault Algorithm 7 The Fault Algorithm 8 Edellä esitetty algoritmi voidaan helposti muuttaa kaksiulotteiseksi. Tällöin arvotaan toimenpiteelle keskipiste, jonka ympärille maskifunktion kuvaaja kierretään. Maskifunktioiksi soveltuvat samat, joita käytettiin yksiulotteisessa tapauksessa. Yksinkertainen kukkula saadaan aikaan käyttämällä maskina ympyrän kaarta. Menetelmä voidaan muuntaa suoraksi matemaattiseksi kaavaksi: ( x, y ) = " kukkulan _ keskusta" 1 1 ( x, y) = " mitattava _ piste" d = " kukkulan_ säde" h = " pisteen _ korkeus" h = d (( x x ) + ( y y ) ) 1 1 Copyright Markku Mielityinen 00 13 Copyright Markku Mielityinen 00 14 The Fault Algorithm 9 The Fault Algorithm 10 Jotta kartan korkeusarvoja voidaan käsitellä standardeilla menetelmillä, tulee ne normalisoida [0,1]-välille. Toimenpide onnistuu yksinkertaisella kaavalla: z norm = ( z z ) ( z z ) min max min Toisaalta skaalan huomiointi voidaan sisällyttää myös käsittelevään algoritmiin. Copyright Markku Mielityinen 00 15 Copyright Markku Mielityinen 00 16 The Fault Algorithm 11 The Fault Algorithm 1 Esitetty algoritmi tuottaa maastopintoja, jotka kattavat koko ruudukon. Algoritmia voidaan kuitenkin helposti muuttaa sellaiseksi, että sillä voidaan tuottaa saarimaisia karttoja, joissa vesi ympyröi kaikkea maa-aluetta. Käyttämällä ruudukon keskelle keskitettyä polaarikoordinaatistoa voidaan korotusten jakaumaa muuttaa siten, että maasto kohoaa keskimäärin enemmän alueen keskustassa, jolloin tuloksena saadaan saari. Algoritmin luomien maastojen korkeusjakaumat ovat suunnilleen tasajakautuneita. Joskus halutaan karttoja, joissa laaksot ja vuorenhuiput ovat tasaisia, mutta näiden välissä on jyrkät reunat. Efekti saadaan aikaan skaalaamalla alkuperäinen korkeusinformaatio epälineaarisella funktiolla. Menetelmä soveltuu pienin muutoksin myös monien muiden efektien aikaansaamiseen. Θ = rand[0,π ] d = rand[0, size / radius] x = size/ + cosθ * d y = size/ + sin Θ* d Copyright Markku Mielityinen 00 17 Copyright Markku Mielityinen 00 18 Copyright Markku Mielityinen 00 3
Mid Point Displacement 1 r=1.0 r=.0 r=0.5 Välipisteen variointi eli plasma-algoritmi luo iteratiivisesti tarkentuvan ruudukon maaston pinnasta. Pinnan tarkkuus määräytyy käytetyn rekursion syvyydestä. N:n askeleen syvyinen rekursio tuottaa (^N+1)*(^N+1) kokoisen ruudukon. Maaston tasaisuuteen voidaan vaikuttaa säätämällä regularisointitermiä r. Arvolla r=1 saavutetaan varsin realistisesti kumpuileva maasto. Arvo r= johtaa varsin epätasaiseen maastoon, johon on ehkä sovellettava jonkinlaista silottavaa ydintä. Arvo r=0.5 johtaa lievästi kumpuilevaan maastoon, joka on myös käyttökelpoinen. Copyright Markku Mielityinen 00 19 Mid Point Displacement Algoritmin suoritus alkaa x ruudukosta, jonka nurkkapisteiden korkeus tunnetaan. Ensimmäisessä työvaiheessa lasketaan neliön keskustaan uusi piste (diamond step): E= ( A + B + C + D)/ rand( [ d, d] Tämän jälkeen lasketaan reunoille neljä uutta pistettä (square step): F = ( A + C + E + E) / G = ( A + B + E + E)/ H = ( B + D + E + E)/ I = ( C + D + E + E) / Lopuksi päivitetään satunnaisluku-generaattorin skaalaa: r d = d Copyright Markku Mielityinen 00 0 Mid Point Displacement 3 Particle Deposition 1 Ruudukon tarkennusta jatketaan rekursiivisesti muodostuneihin uusiin neliöihin. Diamond Step: J = ( A + G + F + E)/ K = ( G + B + E + H )/ L = ( F + E + C + I) / M = ( E + H + I + D) / Square Step: N = ( K + A + J + F) / O = ( L + A + G + J )/ P = ( J + G + K + E)/ Q = ( F + J + E + L)/ Ja tätä jatketaan, kunnes saavutetaan haluttu topografinen tarkkuus. Algoritmin suoritus alkaa sopivan kokoisesta ruudukosta, jonka kaikki korkeudet on asetettu samalle vakioarvolle. Ensimmäisenä valitaan ruudukon satunnainen piste (x,y), jota muutetaan satunnaislukugeneraattorin antamalla korkeudella: p[ x, y] = p[ x, y] + rand( rand( [ d, d] Tämän jälkeen siirrytään seuraavaan pisteeseen käyttäen aina samaa siirtymäfunktiota. Siirtymä voidaan suorittaa esimerkiksi liikkumalla satunnaiseen suuntaan: switch(rand()%4) { case 0: x--; break; case 1: x++; break; case : y--; break; case 3: y++; break; Copyright Markku Mielityinen 00 1 Copyright Markku Mielityinen 00 Particle Deposition Particle Deposition 3 Tuhannella iteraatiokierroksella saavutetaan jo varsin kelvollinen, joskin teräväkulmainen maaston pinta. Maaston realistisuutta voidaan parantaa vähentämällä ylimääräistä epätasaisuutta käyttäen ruudukkoon jotain suodatinta. Keskiarvosuodin luetteloi mitattavan pisteen ja sen naapuripisteet ja valitsee uudeksi korkeudeksi listan keskiarvon. Mediaanisuodin luetteloi mitattavan pisteen ja sen naapuripisteet ja valitsee uudeksi korkeudeksi laaditun listan mediaanin. Suotimien naapurusto voidaan määrätä yksinkertaisella binäärimaskilla. Euklidisesta metriikasta johtuen maskit ovat yleensä pyöreitä. Sopivan suodattimen käytöllä päästään varsin realistisiin maaston pintoihin. Menetelmä tuottaa helposti saarimaisia karttoja, joissa kartan äärialueet jäävät alkuasetuksiinsa. Tilannetta voidaan parantaa kasvattamalla käytettyjen iteraatiokierrosten määrää ja parantamalla liikkumisen ohjaukseen käytettävän funktion heuristiikkaa. Kulkusuunnan valinta voi perustua todennäköisyysfunktioon, joka suosii etenemistä topografisessa mielessä alaspäin. Todennäköisyysfunktion muodostuksella voidaan samalla kontrolloida maaston epätasaisuutta, eikä suodattimen käyttöä välttämättä edes tarvita. Copyright Markku Mielityinen 00 3 Copyright Markku Mielityinen 00 4 Copyright Markku Mielityinen 00 4
Planeettojen generointi 1 Planeettojen generointi Aiemmin esitetyt tasokarttojen generointialgoritmit voidaan helposti yleistää toimimaan myös pallon pinnalla. Siinä missä tasokarttojen tapauksessa pisteitä liikutettiin ylös ja alaspäin, käytetään pallopinnan tapauksessa pisteen euklidista normia, jota kasvatetaan ja vähennetään samassa suhteessa. Aiemmin esitetty Fault-algoritmi voidaan helposti yleistää toimimaan myös pallon pinnalla. Siinä missä aiemmin ruudukko jaettiin kahtia, jaetaan nyt origokeskisen pallon avaruus puoliksi käyttäen origon kautta kulkevaa tasoa. Satunnainen taso voidaan muodostaa helpoimmin arpomalla satunnainen suuntavektori, jonka normaalin kyseinen taso muodostaa. Copyright Markku Mielityinen 00 5 Copyright Markku Mielityinen 00 6 Planeettojen generointi 3 Planeettojen generointi 4 Käytettäessä yksinkertaista kynnysfunktiota kasvatetaan arvotun tason yläpuolella olevien pisteiden normia (pisteen etäisyyttä origosta) d:llä. Vastaavasti tason alapuolella olevia pisteitä siirretään lähemmäs origoa. begin iteration n = random vector foreach vertex v begin s = dotproduct(n, v) if s > 0 v+=d else v-=d end end Jo 100 iteraatiokierroksella saavutetaan varsin realistisen näköisiä lopputuloksia. Tarkemman tarkastelun jälkeen huomataan kuitenkin yksi menetelmän puute. Planeetan etu ja takapuoli muistuttavat toisiaan. Etupuolella olevat maaalueet kuvautuvat kääntöpuolella merialueiksi ja vastaavasti etupuolen meret kääntöpuolen maaalueiksi. Copyright Markku Mielityinen 00 7 Copyright Markku Mielityinen 00 8 Planeettojen generointi 5 Planeettojen generointi 6 Alkuperäistä algoritmia voidaan parantaa siirtämällä avaruuden jakavaa tasoa satunnaisen etäisyyden päähän origosta. begin iteration n = random vector d = d*(rand()%? 1.0 : -1.0) foreach vertex v begin v = n - n s = dotproduct(n, v) if s > 0 v+=d else v-=d end end Korjattu algoritmi tuottamat planeetat eivät kärsi symmetrian aiheuttamasta samankaltaisuudesta. Siirron d suuntaa joudutaan varioimaan koska tason siirto origosta johtaa siihen, että kauemmas työnnettäviä pisteitä on käytännössä aina vähemmän kuin niitä, joita vedetään lähemmäs. Näin ollen pinnan keskimääräinen säde vähenisi alkuperäisen pallon säteestä. Copyright Markku Mielityinen 00 9 Copyright Markku Mielityinen 00 30 Copyright Markku Mielityinen 00 5
S Ekosysteemi 1 Ekosysteemi Kasvillisuuden kehitystä voidaan ohjata joukolla parametreja, jotka kuvaavat kasvupaikan suotuisuutta. Tyhjä maastopinta ei ole realistisen näköinen, kuin vasta hyvin korkealta (avaruudesta) katsottuna. Maapinnan päällä on lähes aina joukko erottuvia objekteja kuten kiviä kasveja ja eläimiä. Kivien sijoittaminen voidaan tehdä suhteellisen vapaasti. Kasvien suhteen joudutaan suorittamaan jo huomattavasti enemmän pohdintaa. Kasvit menestyvät vain tietynlaisissa elinolosuhteissa. Lisäksi kasvien lisääntymismenetelmät vaikuttavat niiden jakautumiseen alueella. Juurista leviävät kasvit muodostavat tiheitä kasvustoja eikä omenakaan kauas puusta putoa. Siemenien avulla leviävät kasvit voivat hajota laajemmalle alueelle. Eläinten lisääminen karttaan luo loppusilauksen, jolla hyvä malli muuttuu erinomaiseksi. Copyright Markku Mielityinen 00 31 Korkeus Suhteellinen korkeus Kaltevuus Kaltevuuden suunta Fraktaali satunnaisuus Kasvupaikan korkeus asetetusta nollatasosta (yleensä meren pinta). Korkeuden kasvaessa kasvuolosuhteet muuttuvat yhä vaativimmiksi. Kasveilla on yleensä yläraja, jota korkeammalla ne eivät menesty. Korkeuden kasvaessa saman lajin kasvien koko yleensä pienenee. Suhteellinen korkeus kuvaa pisteen asemaa suhteessa paikalliseen alueelliseen korkeuteen. Negatiiviset korkeudet kuvaavat laaksoja, jotka ovat usein suojaisampia kasvupaikkoja. Positiiviset korkeudet kuvaavat kumpuja, joiden kasvillisuus on haavoittuvampaa luonnon voimille. Kaltevuus vaikuttaa kasvien kykyyn hankkia vettä. Jyrkältä maalta vesi valuu nopeasti pois ja siten kasvillisuus on niukempaa. Kaikkein jyrkimmät maaston kohdat eivät kykene sitomaan edes aluskasvillisuutta, jolloin alla oleva kallio tulee näkyviin. Kaltevuuden suunta vaikuttaa siihen kuinka paljon kasvillisuus saa valoa. Etelänpuoleiset rinteet saavat runsaasti valoa pohjoisten rinteiden jäädessä hämäriksi. Lisäksi suunta vaikuttaa siihen kuinka haavoittuvia kasvit ovat esimerkiksi pohjoistuulelle. Edellisten lisäksi kasvien menestyminen riippuu lukuisista muista satunnaisemmista ilmiöistä, kuten luonnonilmiöistä, tuholaisista jne. Kaikkia näitä ei voida, eikä ole edes tarpeen huomioida, sillä satunnaisuutta voidaan kuvata stokastisilla malleilla. Copyright Markku Mielityinen 00 3 Ekosysteemi 3 Ekosysteemi 4 Kasvillisuus voidaan jakaa korkeuden mukaisiin kerroksiin. Kerroksia voidaan käyttää hyväksi myös piirtovaiheessa (LOD). Edellä esitetyt parametrit voidaan laskea helposti käytettävissä olevasta topografisesta kartasta: Taso Ruudun leveys Kasvin korkeus Kasvillisuus Pinta 0 1 3 4 5 6 7 8 km 4 km km 1 km 51 m 56 m 18 m 64 m 64 m 3 m 16 m 8 m 4 m m 1 m 50 cm - Isot puut Puut Pienet puut Isot pensaat Pensaat Pienet pensaat ja pitkä ruoho Ruoho - Pienemmät puut, pensaat ja ruoho Pienemmät puut, pensaat ja ruoho Pensaat ja ruoho Pienet pensaat ja ruoho Ruoho Lyhyt ruoho, pienet kasvit ja kivet Pienet kasvit ja kivet h 0 x ( f ( x + h, y) f ( x h, y))/ h 0 y ( f ( x, y + h) f ( x, y h))/... Slope = x + y... x y... norm norm = x / x + 1 = y / y + 1 Slope = Slope / Slope + 1 norm 8 3 m 5 cm Pienet kasvit ja kivet Maa Copyright Markku Mielityinen 00 33 Copyright Markku Mielityinen 00 34 Ekosysteemi 5 Ekosysteemi 6 Lasketut parametrit voidaan yhdistää yhteistodennäköisyyksiksi normalisoimalla alkuperäiset parametrit samalle asteikolle, jonka jälkeen ne muutetaan epälineaariselle asteikolle. Kaavoissa x on alkuperäinen parametri, y normalisoitu parametri ja z regularisoitu parametri. Regularisointitermi S vaikuttaa asteikon muutoksen jyrkkyyteen. x i x avg y i = x x max min 1 z i = ( ) Lopuksi kaikki lasketut regularisoidut parametrit z kerrotaan yhteen (oletetaan että parametrit ovat riippumattomia toisistaan vaikka näin ei luonnollisestikaan ole) ja näin saadaan haluttu yhteistodennäköisyys. Menetelmää voi tehostaa lisäämällä kaavaan parametrityyppien prioritodennäköisyydet. y i p = i z i Copyright Markku Mielityinen 00 35 Copyright Markku Mielityinen 00 36 Copyright Markku Mielityinen 00 6
Pinnan valaistus 1 Pinnan valaistus Kolmion pinnan määräämän tason normaali voidaan laskea yksinkertaisella kaavalla. Ensimmäiseksi lasketaan kaksi tasossa sijaitsevaa vektoria: v1 = t t1 v = t3 t1 Tason normaali voidaan laskea kahdesta tasossa sijaitsevasta vektorista käyttäen ristituloa: nx = v1. y * v. z v1. z * v. y ny = v1. z * v. x v1. x * v. z nz = v1. x * v. y v1. y * v. x Lopuksi saatu vektori normalisoidaan yksikkövektoriksi: n = n n Käytettäessä kolmiokohtaisia normaaleja tulee kolmioiden välisistä kulmista usein häiritsevän selviä. Kolmiokohtaisten normaalien sijaan käytetäänkin usein pistekohtaisia normaaleja jolloin käyttämällä kolmion piirrossa Gouraudsävytystä saavutetaan yhtenäisen näköinen pinta. Pistekohtainen normaali lasketaan pisteeseen kytkettyjen kolmioiden normaaleista: v = v1 + v3 + v34 + v41 Lopuksi saatu normaali normalisoidaan yksikkövektoriksi: v = v v Copyright Markku Mielityinen 00 37 Copyright Markku Mielityinen 00 38 Pinnan valaistus 3 Pinnan valaistus 4 Maastopintojen valoisuutta laskettaessa ei ole välttämätöntä käyttää yhtä tarkkoja menetelmiä kuin esimerkiksi liikuteltavien kappaleiden tapauksessa. Realistisen näköiset varjot voidaan laskea esimerkiksi käyttäen yksinkertaista Lambert in cosini lakia. Yksinkertaiset mallit riittävät, sillä staattisissa valomalleissa ei esiinny häiritseviä siirtymiä. Esimerkki edellä esitetyn valaistusmallin käytöstä. Kuvasta nähdään kuinka auringon puolella olevat rinteet saavat hyvin valoa, kun taas varjoon jäävät rinteet jäävät paljon tummemmiksi. Kuvan esimerkki havainnollistaa myös käytetyn lokaalin valaistusmallin puutteet. Kukkuloiden taakse ei muodostu realistisia katvealueita. Realistisemmat varjostukset saadaan käyttämällä jotain globaalia valomallia. Copyright Markku Mielityinen 00 39 Copyright Markku Mielityinen 00 40 Pinnan valaistus 5 Pinnan valaistus 6 Muodostamalla säde kulmapisteestä aurinkoon voidaan määritellä onko pisteen ja valonlähteen välillä mahdollisesti jokin varjostava este. Jokaiselle esteelle voidaan määrittää sen läpi päästämän valon intensiteetti. Pisteen A tapauksessa kukkula ei päästä läpi yhtään valoa. Pistettä B varjostaa joukko kuusia, joista kukin päästää oksiensa raoista lävitseen 50% saamastaan valosta. Metsän läpi päästämä valo saadaan laskemalla yhteen puiden aiheuttama yhteisvaikutus. Pisteen B tapauksessa valo kulkee kahden puun läpi ja pisteeseen saapuu näin ollen 5% alkuperäisestä valomäärästä. Laadukkaat pinnat sisältävät helposti kymmeniä, jopa satoja tuhansia kulmapisteitä, jolloin reaaliaikaisen valaistuksen laskeminen ei onnistu nykyisillä laitteistoilla. Tämän vuoksi kulmapisteisiin sisällytetään yleensä valmiiksi laskettu valaistusinformaatio. Tällöin menetetään luonnollisesti valaistuksen dynaamisuus. Käytännössä tästä ei kuitenkaan ole juurikaan haittaa sillä tarvittavat liikkuvat varjot voidaan tuottaa esimerkiksi valokarttojen avulla. Lisäksi nykyiset näytönohjaimet hyötyvät staattisesta rakenteesta, joka voidaan kirjoittaa suoraan ohjaimen muistiin ja piirtää siten nopeammin näytölle. Copyright Markku Mielityinen 00 41 Copyright Markku Mielityinen 00 4 Copyright Markku Mielityinen 00 7
ROAM 1 ROAM Kartan kehitys aloitetaan jakamalla neliön muotoinen ruudukko kahtia ja soveltamalla rekursiivisesti etenevää paloittelijaa kahteen muodostuvaan kolmioon. Kehitettävä kolmiojako voidaan tallentaa esimerkiksi binaari puuhun. ROAM:in tavoitteena on laskea reaaliajassa tarvittava kolmiointi. Kartasta saadaan näin dynaaminen, jolloin maaston topografiaan voidaan tehdä muutoksia. Kolmioinnissa lähialueet kuvataan tarkemmin kuin kauempana olevat alueet. Lisäksi kolmiointia voidaan ohjata maaston vaihteluiden mukaan, jolloin jyrkkien vaihteluiden alueille sijoitetaan enemmän kolmioita. Kolmioon liittyvää termistöä. Copyright Markku Mielityinen 00 43 Copyright Markku Mielityinen 00 44 ROAM 3 Binary Trees ROAM-kolmiointi johtaa helposti tilanteisiin, joissa tarkemman neliön ja epätarkemman neliön väliin jää reikiä. Vika voidaan korjata asettamalla jakoehto, joka sanoo että kolmion jako johtaa myös naapurikolmion jakoon. Binääripuut jakavat avaruuden tason etu- ja kääntöpuolella oleviin lohkoihin. Maastojen visualisoinnissa avaruuden jakoon voidaan käyttää ROAM-algoritmia. Avaruuden jakoa jatketaan rekursiivisesti, kunnes lohkojen sisäinen keskivirhe on ennalta asetettua toleranssirajaa pienempi. Tehokkaammilla algoritmeilla avaruuden jaon ei tarvitse olla näin tasaisesti jakautunut, vaan lisäkolmioita saadaan sinne, missä niitä kipeimmin kaivataan. Yhden kolmion jakaminen voi johtaa edelleen muiden kolmioiden jakamiseen. Copyright Markku Mielityinen 00 45 Copyright Markku Mielityinen 00 46 Quad-trees Oct-trees Nelipuut jakavat neliön muotoisen ruudukon neljään aliosaan ja rekursiota jatketaan muodostuneisiin aliosiin, kunnes alueiden sisäiset muutokset ovat toleranssin rajoissa. Nelipuilla kuvattavan maaston on oltava yksikerroksinen, eli siinä ei saa olla toistensa päälle sijoittuvia kielekkeitä. Kahdeksanpuut toimivat nelipuiden tapaan, mutta näistä poiketen ne voivat sisältää kolmioita useissa kerroksissa. Näin ollen maastoon voidaan sijoittaa sisään mentäviä luolia ynnä muita monimutkaisempia rakenteita. Copyright Markku Mielityinen 00 47 Copyright Markku Mielityinen 00 48 Copyright Markku Mielityinen 00 8
VOXEL 1 VOXEL Voxel maastopintojen piirrossa käytetään säteenseurantasovelluksista tuttuja menetelmiä. Katselupisteestä ammutaan joukko säteitä, jotka maastoon osuessaan piirtävät kyseiseen kohtaan kolmiulotteisen pisteen. Jos säteiden määrä on vähäinen, näkyy tämä maastopinnan rakeisuutena. Laskennallisesti erittäin raskasta mallia voidaan keventää rajoittamalla katselukulmia (DoF) mahdollisimman paljon. Pinnan piirto voidaan aloittaa alhaalta ylöspäin, jolloin voidaan hyödyntää maaston jatkuvuutta. Sädepisteen jälkeen voidaan suoraa piirtää seuraavat pisteet kunnes maasta alkaa laskea ja jää näin edellisten pisteiden taakse. Tällöin lasketaan uusi säde, jonka kulma riittää kummun ylittämiseen ja tätä jatketaan, kunnes käsitelty kulma kasvaa yli kameran maksimikulman. Varsinainen säteenseuranta voidaan toteuttaa kahdella tavalla. Copyright Markku Mielityinen 00 49 Copyright Markku Mielityinen 00 50 VOXEL 3 Pinnan teksturointi 1 Perusalgoritmia voidaan parantaa monilla menetelmillä: 1) Lähellä oleviin pisteisiin sovelletaan ditherointi, jolloin palikkamaisuus vähenee. ) Kumpujen taakse lasketaan staattiset varjot. 3) Kartan piirrossa käytetään Mip-mappingia lähellä tarkkaa ja silti kokonaisuutena nopeaa. 4) Voxel-pisteet pikselin kokoisia käytetään sumua vähentämään yksityiskohtia. 5) Voxel-pisteet 4 pikselin kokoisia. Sumu vähentää häiritsevää palikkamaisuutta. 6) Lähellä oleviin pisteisiin sovelletaan tekstuurien sumeaa yhteensovittamista. Maastopinnan teksturointi voidaan suorittaa kahdella tavalla. Käytössä voi olla yleinen tekstuuripankki, jota sovelletaan jokaiseen kolmioon erikseen. Nykyisillä laitteistoilla on kuitenkin järkevämpää muodostaa yksi suuri tekstuuripinta, joka levitetään koko pinnan ylle. Tekstuurin generoinnissa tarvitaan tietoja maaston valaistuksesta ja eri kohteiden maastotyypistä. Valaistus voidaan joko laskea tai käyttää valmista valokarttaa. Maastotyypin valinta voidaan suorittaa joko korkeuteen rinnastettuna tai vaihtoehtoisesti erillisellä tekstuurikartalla. Copyright Markku Mielityinen 00 51 Copyright Markku Mielityinen 00 5 Pinnan teksturointi Pinnan teksturointi 3 Pinnan teksturointi muodostetaan tasoittain päällekkäin ladottavista komponenteista. Eri tasojen käyttö voidaan rinnastaa kartan topografiseen korkeuteen, jolloin tasojen käyttöä voidaan säädellä yksinkertaisella sumealla jäsenyysfunktiolla. Käytännössä jäsenyysfunktiot muutetaan jokaiselle tasolle yksilöllisiksi alphakanaviksi, jolloin pinnan tekstuuri muodostuu yksinkertaisesti piirtämällä maskit alphakanavan ohjaamana. Esimerkin tapauksessa maasto koostuu neljästä erilaisesta tasosta. Alimpana on kallio. Alavilla mailla kasvaa ruohikkoa, joka vaihtuu hitaasti vuorten huippujen jääpeitteeseen. Lopputuloksena saatu tekstuuri sisältää kaiken tarvittavan informaation, eikä aikaa vieviä välivaiheita piirron aikana tarvita. Lopputulos on lisäksi erittäin realistisen näköinen. Copyright Markku Mielityinen 00 53 Copyright Markku Mielityinen 00 54 Copyright Markku Mielityinen 00 9
Sumu Taivaan mallintaminen Sumua on perinteisesti käytetty korvaamaan puutteellista suorituskykyä. Jos katselupiste sijaitsee sumun keskellä, on luonnollista, että kappaleet ikään kuin häviävät sumuun. Mallinnuksessa sumulla voidaan määrätä tiettyä etäisyyttä kauempana olevat kolmiot näkymättömiksi, jolloin niitä ei tietenkään tarvitse piirtää ja näin piirrettävien kolmioiden määrä laskee. Parempia efektejä saadaan aikaan käyttämällä paikoittaista sumua (volumetric fog), jolloin sumun määrä voi vaihdella alueittain. Taivaankannen mallintaminen on olennainen osa maaston visualisointia. Muutoinhan taivas näyttäisi mustalta, joka viittaisi kuumaiseen kaasuttomaan ilmakehään. Taivaan kantta varten tuotetaan laskennallisesti kolmiosta muodostuva puolipallo (sky dome). Taivaan tekstuurina voidaan käyttää kalansilmälinssillä otettuja kuvia tai vaikkapa plasmageneraattorilla tuotettuja bittikarttoja. Edistyneemmissä malleissa taivaan tulee myös olla animoitu, jolloin pilvet liikkuvat realistisesti. Liiallinen sumun käyttö johtaa suttuiseen lopputulokseen, josta ei käytännössä näe yhtään mitään ja siten sumun käyttöä on aina syytä harkita tarkoin. Copyright Markku Mielityinen 00 55 Copyright Markku Mielityinen 00 56 Puiden mallintaminen Liikkuvien kappaleiden lisääminen Realistiset maastot ovat usein täynnä erilaisia kasveja. Jokaisen kasvin tarkka piirtäminen on vielä pitkään liian raskasta reaaliaikaisiin sovelluksiin. Sovelluksien nopeutta voidaan parantaa yksinkertaisella LOD-tekniikalla. Kaukana olevat kasvit piirretään vain neljällä kolmiolla ja detaljin määrää kasvatetaan asteittain. Liikkuvat kappaleet eivät kuulu varsinaisesti maastojen piirtoon. Yleensä objektien toteuttamiseen käytetään jotakin olemassa olevista kappalemalleista, kuten MD, ASE jne. Koko maailman piirtäminen voidaan suorittaa esimerkiksi siten, että ensimmäisen piirretään maaston pinta. Tämän jälkeen lisätään maaston kappaleet, kuten tiet, puut ja kivet. Lopuksi piirretään varsinaiset objektit käyttäen syvyyskarttaa (Z-buffer), jolloin objektit piirtyvät automaattisesti oikein näkyviin. Copyright Markku Mielityinen 00 57 Copyright Markku Mielityinen 00 58 Lens Flare Lähteet Kameroja ynnä muita optisia laitteita käytettäessä kuvaan saattaa muodostua valon taittumisesta seuraava lens flare efekti. Vaikka efekti heikentää näkyvyyttä, on se realistisuuden lisäämiseksi osana lähes jokaista maastomoottoria. Efektiä varten lasketaan ensin ympyrämäinen valokeila. Keilassa voidaan haluttaessa käyttää valkoisen sijaan myös muita värisävyjä. Piirtovaiheessa valokeila piirretään käyttäen Flipcode: http://www.flipcode.com/ CFXweb: http://www.cfxweb.net/ Lighthouse 3D: http://www.lighthouse3d.com/ Terrain Generation Tutorial: http://www.robot-frog.com/3d/hills/ Terrain Tutorial: http://www.lighthouse3d.com/opengl/terrain/ Spectral Syntesis Noise for Creating Terrain: http://www.gamedev.net/reference/programming/features/noiseterrain/ Sperical Landscapes: http://freespace.virgin.net/hugo.elias/models/m_landsp.htm Modelling fake planets: http://astronomy.swin.edu.au/~pbourke/terrain/planets/ Modeling of ecosystems as a data source for real-time terrain rendering: http://mzone.mweb.co.za/residents/jhammes/hammes.pdf Real-Time Dynamic Level of Detail Terrain Rendering with ROAM: http://www.gamasutra.com/features/0000403/turner_01.htm Binary Triangle Trees and Terrain Tesselation: http://www.gamedev.net/reference/articles/article806.asp Application of 3D Delaunay Triangulation algorithms in Geoscientific modelling: http://www.ncgia.ucsb.edu/conf/santa_fe_cd- ROM/sf_papers/lattuada_roberto/paper.html Introduction to Octtrees: http://www.flipcode.com/tutorials/tut_octrees.shtml Voxel Landscape Engines: http://www.flipcode.com/voxtut/ GDC 001: Implementing Multi-colored Volumetric Fog Without Using up Texture Stages: http://www.gamasutra.com/features/001033/baeza_01.htm Sky Domes: http://www.flipcode.com/tutorials/tut_skydomes.shtml Jääkäri: http://www.wiredman.net/ Executor: http://www.saunalahti.fi/~kkhuolto/executor/ Typhoon: http://gpi.infomedia.it/typhoon/ Copyright Markku Mielityinen 00 59 Copyright Markku Mielityinen 00 60 Copyright Markku Mielityinen 00 10
Screenshot 1 Screenshot Copyright Markku Mielityinen 00 61 Copyright Markku Mielityinen 00 6 Screenshot 3 Screenshot 4 Copyright Markku Mielityinen 00 63 Copyright Markku Mielityinen 00 64 Screenshot 5 Screenshot 6 Copyright Markku Mielityinen 00 65 Copyright Markku Mielityinen 00 66 Copyright Markku Mielityinen 00 11