Tech Filet

Kuten pelitkin, nämä tech filet olivat Suomipelit.comissa sivuston sulkeuduttua. Näin ollen niihin saattaa sisältyä epämääräisiä viitteitä asioihin, joita ei enää ole olemassa, ja joskus jokin saattaa näkyä väärin. Pahoitteluni.

Tech filet olivat yksittäisten kirjoittajien kirjoittamia, vähän blogimaisempia tekstejä, joiden tarkoitus oli esimerkiksi kertoa projektien etenemisestä, tai opettaa jotain yksittäisiä ohjelmointiin liittyviä asioita.

Palaa tech file -listaan

3D-enginen kehittelyä, teoriassa

9.6.2002 23:53 julkaistun artikkelin on kirjoittanut Jarkko Parviainen.

Aurinko on taas mukavasti paistellut, ja ihokin kärventynyt. Koodia ei paljoa ole tullut tehtyä, vain koulun ja töiden kannalta pakolliset pätkät. Käytännössä olen siis kotona ollessani täysin koodaamatta. Vaikka tällaiset suvantovaiheet vaikuttanevat siltä, että mitään koodaamista edistävää ei tapahdu, on totuus toisenlainen. Useat ideat ovat kypsyneet päässäni lähes toteuttamiskelpoisiksi, ja yhdestä niistä aionkin tähän hieman enemmän kirjoittaa. Kirjoittelen asiat tähän siinä järjestyksessä kun aloin niitä miettimään, joten saatte samalla hieman kuvaa siitä, millaista 3D-enginen suunnittelu ainakin tässä tapauksessa on ollut.

Työstämäni 3D-engine (KiWi) sisältää jo näkyvyystarkastelun johon olen tällä hetkellä tyytyväinen. Ainoa ongelma on kamerasta hyvin kaukana olevat objektit. Kameran näköetäisyyttä ei voi lisätä kovinkaan paljoa, kun syvyyspuskurin (eli z-buffer) virheet alkavat esiintyä ja laskevat kuvanlaatua merkittävästi. Lisäksi kaukaisten objektien geometrian piirto on suhteellisen hidasta LOD-tekniikoista huolimatta (Level Of Detail, tarkkuustaso) ja niistä näkyy muutenkin kovin vähän. Engine nopeutuisi huomattavasti jos nämä 2 ongelmaa saataisiin ratkaistua.

Hetken mietittyäni ja asiaa tutkittuani tulin tulokseen, että Image Based Rendering (eli kuvapohjainen piirto) on todennäköisesti paras tapa poistaa yllä mainitut ongelmat. Perinteinen kolmioiden piirto ruudulle on geometriapohjaista piirtoa, eli esinettä kuvaa suoraan sen 3-ulotteinen malli. Kuvapohjaisessa piirrossa 3-ulotteinen malli korvataan sitä esittävällä kuvalla. Kuva voidaan muodostaa piirtämällä malli esimerkiksi tekstuuriin. Myöhemmin tekstuuria käytetään aina silloin kun 3D-malli tarvitaan piirtää ruudulle. Kokonaisen, satojakin kolmioita sisältävän, 3D-mallin sijasta piirrettäisiin siis ruudulle vain pari kolmiota jotka käyttävät aiemmin luotua tekstuuria. Piirretystä kuvasta käytetään nimitystä Impostor, huijari.

Aluksi ajattelin, että jokaiselle 3D-mallille voisi lisätä viimeiseksi LOD-tasoksi Impostor-tekstuurin. Tällöin Impostoreita käytettäisiin loogisesti laskeutuessa LOD-hierarkiaa alaspäin. Tämä ei kuitenkaan ole kovinkaan hyvä ratkaisu. KiWi:ssä 3D-malleja voi olla käytössä satoja, ellei tuhansia ja jos jokaiselle sallitaan yksi 256x256-tekstuuri sisältämään Impostor-kuvat muistivaatimukset kasvaisivat huimasti. Tämän lisäksi useiden Impostoreiden piirtäminen erikseen ei ole nopein mahdollinen tapa korvata geometrian piirtoa. Ajattele esimerkiksi ylhäältä nähty metsä, jossa on tuhansia puita. Vaikka kaikki kaukaisimmat puut korvataan impostoreilla, ne jouduttaisiin silti piirtämään erikseen. Nopeinta olisikin saada ne kaikki piirrettyä yhdellä kertaa. Tästä pääsin seuraavaan ideaan, joka on hyvinkin vanha tekniikka: ympäristökartoitukseen (Environment Mapping).

Perinteisesti ympäristökartoituksesta puhuttaessa tarkoitetaan objektin tekstuurin ja tekstuurikoordinaattien valintaa siten, että se näyttää kuvastavan piirrettynä mahdollisimman hyvin objektin ympäristöä. Ympäristökartoitusta tarvitsevia esineitä ovat esimerksi ovenkahvat ja muut metalliesineet. Tunnetuimpia vaihtoehtoja ympäristökartoituksen toteuttamiseen on Spherical Environment Mapping (objekti on kuvitellun pallon sisällä), Dual Paraboloid Environment Mapping (2 vastakkaista paraboloidia, joiden välissä objekti on) sekä Cubical Environment Mapping (ehkä tunnetuin, eli objekti on kuvitellun kuution sisällä). Näistä viimeisin soveltuu ideaani parhaiten, tietyin erikoiskäsittelyin.

Useimmissa peleissä kerrotaan, että taustat piirretään nk. SkyBoxia käyttäen. Kyseessä on kuitenkin Cubical Environment Mappinging muoto, jossa kuutio piirretään suoraan taustakuvaksi ja muu geometria sen päälle. Taustakuva on yleensä valmiiksi piirretty kuva, joka säilyy aina samana. Skyboxeja voisi kuitenkin piirtää useita päällekäin, ja osan kerroksista pystyisi päivittämään dynaamisesti (eli ohjelman ajon aikana). Koska skyboxeissa kuvattu geometria on kaukana, niitä tarvitsee päivittää vain silloin kun A) kamera on liikkunut tarpeeksi tai B) kuvattu geometria on näkyvästi muuttunut. Eri kerrosten päivitystahti vaihtelisi siis sen mukaan, kuinka kaukana olevaa geometriaa ne kuvaavat. Menetelmä ratkaisee molemmat aiemmin mainitut ongelmat:

1. Syvyyspuskuriongelma korjaantuu, koska eri syvyysalueiden kuvat piirretään tekstuureihin. Tekstuurit piirretään myöhemmin tasan päällekkäin ilman syvyyspuskuria.
2. Piirto nopeutuu, koska useita objekteja saadaan piirrettyä kerralla. Lisäksi KiWin peittävyystarkatelu poistaa kerroksista ne objektit jotka eivät muutenkaan näkyisi, jolloin kerrosten päivitys nopeutuu.
3. Muistia ei kulu läheskään niin paljoa kuin per-objekti impostoreita käytettäessä.

Riippuen kameran näköalueen leveydestä tarvittaisiin 3-5 tekstuuria / skybox-kerros. Useimmissa tapauksissa 3 riittänee hyvin, sillä näköalueen leveys on useimmiten 90', jolloin kuutiosta voi olla näkyvissä maksimissaan vain 3 sivua. 180' leveydellä tarvittaisiin yllä mainittu 5 tekstuuria. Ongelmaksi tässä tavassa jää kuitenkin päivitystiheyden tarkkailu ja kerrosten määrä. Liian harvakseltaan päivitettynä skyboxeihin ilmaantuu katkoksia, jotka näkyvät taustojen grafiikoiden ajoittaisina hyppäyksinä. Jos skyboxeja on liian vähän edellä mainittu ongelma korostuu. Liian usein päivitettynä tai liian montaa kerrosta käytettäessä piirto taas hidastuu. Nämä asiat voi kuitenkin tasoittaa testaamalla ja ajonaikaisella muokkauksella.

Yllä oleva tekniikka on yhä testaamatta käytännössä. Uskon kuitenkin että siinä on potentiaalia, sillä teoriassa se sallii äärettömän pitkät piirtomatkat ilman syvyyspuskuri ongelmia, reaaliajassa. Lopullisen tuloksen saan tietooni testaamalla ja luomalla vertailukäyriä tästä ja muista kehittelemistäni tekniikoista. Kyllä, olen miettinyt yllä olevien lisäksi myös muita tekniikoita kahden alkuperäisen ongelman ratkaisemiseksi.

Kuten huomaatte, suunnitteluprosessi on melkoista ajatusten vilskettä ja vanhojen asioiden uudelleen ajattelemista. Mutta näin tällä kertaa. Ensi kerralla jatketaan muiden aiheiden parissa. Suunnittelun iloa!