TIMO SALOKAS MICROSOFTIN DIRECTX-TEKNIIKKA JA ANTIALIASOINTI. Kandidaatintyö

Samankaltaiset tiedostot
Luento 3: 3D katselu. Sisältö

Tilanhallintatekniikat

Luku 6: Grafiikka. 2D-grafiikka 3D-liukuhihna Epäsuora valaistus Laskostuminen Mobiililaitteet Sisätilat Ulkotilat

Tietokonegrafiikka. Jyry Suvilehto T Johdatus tietoliikenteeseen ja multimediatekniikkaan kevät 2014

Luento 6: Piilopinnat ja Näkyvyys

Peilaus pisteen ja suoran suhteen Pythonin Turtle moduulilla

ELM GROUP 04. Teemu Laakso Henrik Talarmo

Luku 8. Aluekyselyt. 8.1 Summataulukko

Toinen harjoitustyö. ASCII-grafiikkaa

CUDA. Moniydinohjelmointi Mikko Honkonen

Videon tallentaminen Virtual Mapista

Arkkitehtuurikuvaus. Ratkaisu ohjelmistotuotelinjan monikielisyyden hallintaan Innofactor Oy. Ryhmä 14

S09 04 Kohteiden tunnistaminen 3D datasta

S11-09 Control System for an. Autonomous Household Robot Platform

Ohjelmoinnin perusteet Y Python

4. Lausekielinen ohjelmointi 4.1

Osoitin ja viittaus C++:ssa

Ohjelmiston toteutussuunnitelma

S Laskennallinen Neurotiede

Luento 6: Tulostusprimitiivien toteutus

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

15. Ohjelmoinnin tekniikkaa 15.1

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

Loppuraportti. Virtuaali-Frami, CAVE-ohjelmisto. Harri Mähönen projektiassistentti Seinäjoen ammattikorkeakoulu. Versio

ALKUSANAT... 4 ALKUSANAT E-KIRJA VERSIOON... 5 SISÄLLYSLUETTELO... 6

KUVANKÄSITTELY THE GIMP FOR WINDOWS OHJELMASSA

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Matriisit ovat matlabin perustietotyyppejä. Yksinkertaisimmillaan voimme esitellä ja tallentaa 1x1 vektorin seuraavasti: >> a = 9.81 a = 9.

Alkuraportti. LAPPEENRANNAN TEKNILLINEN YLIOPISTO TIETOJENKÄSITTELYN LAITOS Ti Kandidaatintyö ja seminaari

JAVA on ohjelmointikieli, mikä on kieliopiltaan hyvin samankaltainen, jopa identtinen mm. C++

Tampereen yliopisto Tietokonegrafiikka 2013 Tietojenkäsittelytiede Harjoitus

Sisällys. T Tietokonegrafiikan perusteet. OpenGL-ohjelmointi 11/2007. Mikä on OpenGL?

Järjestelmäarkkitehtuuri (TK081702)

Tietorakenteet ja algoritmit

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

Algoritmit 1. Luento 3 Ti Timo Männikkö

Pedacode Pikaopas. Java-kehitysympäristön pystyttäminen

Videon tallentaminen Virtual Mapista

Gimp JA MUUT KUVANKÄSITTELYOHJELMAT

S11-04 Kompaktikamerat stereokamerajärjestelmässä. Projektisuunnitelma

Vektoreita GeoGebrassa.

Tietorakenteet ja algoritmit

TAMPEREEN TEKNILLINEN YLIOPISTO Digitaali- ja tietokonetekniikan laitos. Harjoitustyö 4: Cache, osa 2

WINE API ja Virtualisointiohjelmistot

Hannu Mäkiö. kertolasku * jakolasku / potenssiin korotus ^ Syöte Geogebran vastaus

Nspire CAS - koulutus Ohjelmiston käytön alkeet Pekka Vienonen

Käyttöliittymän muokkaus

Varmuuskopiointi ja palauttaminen Käyttöopas

Ulkoiset mediakortit. Käyttöopas

TIES471 Reaaliaikainen renderöinti

Muita kuvankäsittelyohjelmia on mm. Paint Shop Pro, Photoshop Elements, Microsoft Office Picture Manager

Apuja ohjelmointiin» Yleisiä virheitä

Tietueet. Tietueiden määrittely

Tampereen yliopisto Tietokonegrafiikka 2013 Tietojenkäsittelytiede Harjoitus

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

z 1+i (a) f (z) = 3z 4 5z 3 + 2z (b) f (z) = z 4z + 1 f (z) = 12z 3 15z 2 + 2

7/20: Paketti kasassa ensimmäistä kertaa

Selainpelien pelimoottorit

Kahden suoran leikkauspiste ja välinen kulma (suoraparvia)

Mitä on konvoluutio? Tutustu kuvankäsittelyyn

Järjestelmäarkkitehtuuri (TK081702) Avoimet web-rajapinnat

Algoritmit 1. Luento 1 Ti Timo Männikkö

Valokuvien matematiikkaa

IT-OSAAJA, TIETOJENKÄSITTELYN ERIKOISTUMISOPINNOT

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. FT Ari Viinikainen

Mainosankkuri.fi-palvelun käyttöohjeita

Ulkoiset mediakortit. Käyttöopas

3D-Maailman tuottaminen

TAMPEREEN TEKNILLINEN YLIOPISTO

FuturaPlan. Järjestelmävaatimukset

JOHDATUS TEKOÄLYYN TEEMU ROOS

Tieteellinen laskenta 2 Törmäykset

Tietorakenteet ja algoritmit

Tietorakenteet ja algoritmit - syksy

Määrittelydokumentti

XPages käyttö ja edut Jarkko Pietikäinen toimitusjohtaja, Netwell Oy

T Vuorovaikutteinen tietokonegrafiikka Tentti

Interfacing Product Data Management System

Ohjelmistojen mallintaminen, mallintaminen ja UML

6.6. Tasoitus ja terävöinti

Ohjeissa pyydetään toisinaan katsomaan koodia esimerkkiprojekteista (esim. Liikkuva_Tausta1). Saat esimerkkiprojektit opettajalta.

Action Request System

Esityksen sisältö. Peruskäsitteitä. 3D Grafiikka tietokonepeleissä. Piirto- ja taustapuskuri

Dart. Ryhmä 38. Ville Tahvanainen. Juha Häkli

T Johdatus tietoliikenteeseen ja multimediatekniikkaan Tietokonegrafiikka

Muistimoduulit. Käyttöopas

Luento 1 Tietokonejärjestelmän rakenne

Luento 1 Tietokonejärjestelmän rakenne. Järjestelmän eri tasot Laitteiston nopeus

Matlabin perusteita Grafiikka

Toinen harjoitustyö. ASCII-grafiikkaa 2017

Solidity älysopimus ohjelmointi. Sopimus suuntautunut ohjelmointi

Ohjelmointi 1. Kumppanit

PIKSELIT JA RESOLUUTIO

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

mlvektori 1. Muista, että Jacobin matriisi koostuu vektori- tai skalaariarvoisen funktion F ensimmäisistä

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

Interaktiivisten järjestelmien arkkitehtuuriratkaisu, jolla käyttöliittymä erotetaan sovelluslogiikasta.

Monipuolinen esimerkki

Ulkoiset mediakortit. Käyttöopas

Transkriptio:

TIMO SALOKAS MICROSOFTIN DIRECTX-TEKNIIKKA JA ANTIALIASOINTI Kandidaatintyö Tarkastaja: lehtori Heikki Huttunen Jätetty tarkastettavaksi 9. toukokuuta 2009

I TIIVISTELMÄ TAMPEREEN TEKNILLINEN YLIOPISTO Tietoliikenne-elektroniikan koulutusohjelma SALOKAS, TIMO: Microsoftin DirectX-tekniikka ja antialiasointi Tekniikan kandidaatintyö, 17 sivua, 3 liitesivua Toukokuu 2009 Pääaine: Signaalinkäsittely Tarkastaja: lehtori Heikki Huttunen Avainsanat: Microsoft DirectX, antialiasointi, jälkisuodatus, HLSL Microsoft DirectX -tekniikka on yksi käytetyimpiä tekniikoita, kun kyse on nykyaikaisista tietokonepeleistä tai muista graafista suorituskykyä vaativista sovelluksista. Tekniikka sisältää komponentit muun muassa käyttäjän syötteiden hallintaan, verkkopelaamiseen, sekä ääniefektien ja musiikin toistoon. Tämän työn kannalta pääosassa on kuitenkin sen Direct3D-komponentti, joka tarjoaa ohjelmistokehittäjille rajapinnan grafiikkalaitteiston hallintaan ja 3D-maailmoiden esittämiseen. Yksi häiritsevä tekijä 3D-mallien, kuvien sekä muun grafiikan esittämisessä on aliasoituminen. Aliasoitumisella tarkoitetaan kuvan sisältämien korkeiden taajuuksien laskostumista matalemmille taajuuksille. Tämä ilmenee esimerkiksi kuvassa olevien reunojen porrastumisena. Aliasoitumista tapahtuu aina kun suuren resoluution omaavia 3D-malleja renderöidään pikseleiksi. Sen häiritsevyyttä voidaan kuitenkin vähentää toimenpiteillä, joista käytetään yhteistä nimitystä antialiasointi. Työssä käsitellään kahta pääasiaa, jotka ovat kuvien antialiasointi sekä Microsoftin DirectX-tekniikka. Tarkemmin syvennytään jälkisuodatukseen perustuvaan antialiasointiin sekä DirectX-tekniikan Direct3D-komponenttiin. Työssä käsitellään myös varjostimien asema tietokonegrafiikassa sekä HLSL-kieli, jolla varjostimia on mahdollista ohjelmoida. Työhön sisältyy myös toteutusosa, jossa toteutetaan varjostin HLSL-kielellä DirectX-ympäristöön. Varjostin toteuttaa teksturoidun 3D-mallin antialiasoinnin käyttäen hyväksi työssä esiteltävää jälkisuodatusmenetelmää.

II ALKUSANAT Tämä työ on kirjoitettu osana Tampereen teknillisen yliopiston signaalinkäsittelyn laitoksen kandidaatintyöseminaaria keväällä 2009. Työn aikana opin paljon aiheen lisäksi itse kirjoitusprosessista sekä opinnäytetyön tekemisestä. Haluan kiittää työni ohjaajaa lehtori Heikki Huttusta avusta aiheen valinnassa sekä korvaamattomista kommenteista työn rakenteeseen ja sisältöön liittyen. Kiitos kuuluu myös opponentilleni Pasi Sillanpäälle työhön liittyvistä kommenteista sekä Aleksandralle, joka tarjosi tukea työn vaikeina aikoina. Kiitos myös opiskelutovereilleni työn oikoluvussa auttamisessa. Tampereella 9. toukokuuta 2009 Timo Salokas

III SISÄLLYS 1. Johdanto... 1 2. Antialiasointi... 3 2.1. Aliasoituminen kuvissa... 3 2.2. Jälkisuodatus... 5 2.2.1. Grid-algoritmi... 6 2.2.2. Stokastinen algoritmi... 6 2.2.3. Poisson Disc -algoritmi... 7 2.2.4. Jittered-algoritmi... 7 2.2.5. Käännetty Grid-algoritmi... 8 2.2.6. Adaptiivinen jälkisuodatus... 8 2.2.7. Suodatustulos Grid-algoritmilla... 8 3. Microsoft DirectX 9... 10 3.1. DirectX 9 yleisesti... 10 3.2. Direct3D... 11 3.3. Varjostimet ja HLSL... 12 4. Antialiasointivarjostimen toteutus HLSL-kielellä... 14 5. Johtopäätökset... 17 Lähteet... 18 Liite 1: Matlab-toteutus... 20 Liite 2: HLSL-toteutus... 21

IV TERMIT JA NIIDEN MÄÄRITELMÄT API Ohjelmointirajapinta (engl. Application Programming Interface). BMP Bittikarttakuvien tallentamiseen käytettävä kuvaformaatti, jossa jokaisella kuvapisteellä on sijainti ja väriarvo (engl. Bitmap). Clipping Tietokonegrafiikassa renderöidyn kuva-alueen ulkopuolelle jäävien osien poisleikkaustoimenpiteestä käytettävä termi. Culling Kolmiulotteisessa grafiikassa toisten pintojen taakse jäävien pintojen piirtämättä jättämisestä käytettävä termi. COM Microsoftin vuonna 1993 esittelemä rajapintastandardi, joka mahdollistaa ohjelmistokomponenttien keskinäisen kommunikoinnin (engl. Component Object Model). FFP Direct3D-komponentista löytyvä grafiikkaliukuhihna, joka sisältää joukon ennaltamääriteltyjä funktioita (engl. Fixed Function Pipeline). HAL Laitteistorajapintakerros, jonka avulla laitteistoa on mahdollista ohjata (engl. Hardware Abstraction Layer). MS-DOS Microsoftin vuonna 1981 julkaisema tekstipohjainen käyttöliittymä (engl. Microsoft Disk Operating System). Pikseli Kuvapiste, bittikarttakuvan pienin osa (engl. Pixel). SDK Ohjelmistokehittäjille tarjottavien kehitystyökalujen sarja (engl. Software Development Kit). SVG World Wide Web Consortiumin kehittämä avoin kuvatiedostostandardi skaalattavan vektorigrafiikan esittämiseen XML-kielellä (engl. Scalable Vector Graphics). TCP/IP Usean tietoverkkoprotokollan yhteisnimitys (engl. Transmission Control Protocol / Internet Protocol). Verteksi Solmupiste, jonka avulla voidaan määritellä polygonien muotoja. Tietokonegrafiikassa yhden primitiivimuodon, kolmion, määrittelyyn tarvitaan kolme verteksiä (engl. Vertex). WDM Laiteajureille tarkoitettu sovelluskehys (engl. Windows Driver Model). XML World Wide Web Consortiumin kehittämä merkintäkieli tiedon jäsentämiseen (engl. Extensible Markup Language).

1 1. JOHDANTO Microsoftin DirectX-tekniikka juontaa juurensa PC-pelaamisen alkuaikoihin, jolloin MS-DOS nautti suurta suosiota peliohjelmoijien keskuudessa. MS-DOS:ssa ohjelmoijat pystyivät kutsumaan mitä tahansa käytettävän laitteen käskykantaan kuuluvaa operaatiota ja täten hyödyntämään laitteistonsa koko suorituskyvyn. [1, s. 705] Suoralla pääsyllä laitteistorajapintaan oli kuitenkin myös varjopuoli, sillä ohjelmoijat saattoivat vahingossa tai tarkoituksellisesti muuttaa tai tuhota tiedostoja ja resursseja, jotka eivät kuuluneet itse suoritettavalle ohjelmalle [1, s. 705]. Toinen ongelma liittyi ohjelmien levittämiseen, sillä ohjelmaa suorittavan laitteiston vaihtuessa myös käytettävissä oleva käskykanta saattoi vaihtua, jolloin takuuta toimivuudesta ei välttämättä ollut [2, s. 5]. Tietokoneen yleistyessä erityisesti yrityskäytössä, myös vaatimukset sitä kohtaan nousivat. Tietokoneen tuli olla entistä vakaampi ja turvallisempi käyttää. Ongelma oli ilmeinen MS-DOS-järjestelmällä, joten ohjelmistoyritykset alkoivat kehittää turvallisempia käyttöjärjestelmiä, jotka estivät suoritettavilta ohjelmilta suoran pääsyn laitteistoon. Näistä järjestelmistä yksi suurin oli Microsoftin Windows. [1, s. 705 706] Eston vuoksi peleillä, sekä muilla graafista suorituskykyä vaativilla ohjelmilla, oli kuitenkin entistä vähemmän resursseja käytössään, joten kehittäjät eivät halunneet siirtyä tai kyenneet siirtymään MS-DOS:sta Windowsiin. Tämä johti ristiriitaiseen tilanteeseen Windowsin kannalta, sillä siitä oli tullut graafinen käyttöjärjestelmä, joka kykeni suorittamaan graafisia ohjelmia vain hyvin rajoitetulla suorituskyvyllä. [1, s. 705 706] Vuonna 1994 Microsoft yritti ratkaista ongelmaa julkaisemalla rajapinnan nimeltä WinG, jonka yksi pääominaisuuksista oli mahdollisuus siirtää bittikarttoja nopeasti järjestelmän muistista laitteiston videomuistiin. WinG ei kuitenkaan pystynyt vastaamaan pelien tarpeisiin etenkään koko näytön renderöintiä tarvitsevissa sovelluksissa, mutta Microsoft jatkoi sen kehittämistä. Lopulta julkaistu yksityiskohtaisempi Game SDK -rajapinta vastasi pelinkehittäjien odotuksiin, sillä se mahdollisti suorituskykyä vaativien ohjelmien kehittämisen Windowsille. Kehittäjät pystyivät sen myötä tuomaan peleihinsä myös Windowsin Win32-rajapinnan tarjoamat edut, kuten TCP/IP-rajapinnan sekä useita käyttöliittymäominaisuuksia. [3, s. 54] Pian Game SDK:n julkaisun jälkeen Microsoft huomasi sen ominaisuuksien olevan hyödyllisiä pelien lisäksi myös muissa multimediasovelluksissa, joten Game SDK:n uusi versio sai lisääntyvien multimediaominaisuuksien myötä uuden nimen, DirectX 2 [1, s. 706]. Tästä versiosta lähtien Microsoft on kehittänyt DirectX-nimellä multimediasovellukset ja laitteiston yhdistävää rajapintaa, jota käytetään nykyajan

1. Johdanto 2 suosituimmissa tietokonepeleissä. Uusin versio rajapinnasta on DirectX 10.1, joka julkaistiin helmikuussa 2008 osana Microsoft Windows Vista -käyttöjärjestelmän Service Pack 1 -päivitystä [4]. Tässä työssä käsitellään DirectX 9c -rajapintaa. Se on viimeisin Windows XP - käyttöjärjestelmälle julkaistu DirectX-versio, sillä uusin 10.1-versio on tarkoitettu toimimaan vain Windows Vista -käyttöjärjestelmällä [4]. Rajapinta esitellään aluksi yleisesti, jonka jälkeen perehdytään laajemmin sen Direct3D-osaan. Näiden lisäksi työssä käsitellään kuvien aliasoitumista sekä sitä, miten aliasoitumista voidaan vähentää DirectX:n avulla antialiasoiden. Aliasoitumisella tässä työssä tarkoitetaan kuvan näytteistyksestä johtuvaa reunojen porrastumista. Sitä tarkastellaan käytännönläheisesti esimerkkien avulla sekä esittelemällä yksi antialiasointisuodin toteutetuna DirectXympäristöön.

3 3 2. ANTIALIASOINTI 2.1. Aliasoituminen kuvissa Tietokonegrafiikassa 3D-mallit ja vektorigrafiikka ovat esimerkkejä kuvista, jotka muodostuvat spatiaaliresoluutioltaan äärettömän tarkoista muodoista. Käytettävät muodot ovat jatkuvia esityksiä primitiivisistä muodoista, kuten esimerkiksi viivoista, ympyröistä ja monikulmioista, joista käytetään myös termiä polygoni (engl. polygon). Esimerkiksi SVG-formaatin mukaiset vektorikuvat ovat XML-dokumentteja, jotka sisältävät tiedon kuvissa olevista muodoista ja muotojen sijainneista [5]. Toisenlaista lähestymistapaa kuvien määrittelyyn edustavat esimerkiksi BMP-formaatin mukaiset bittikarttakuvat, jotka koostuvat joukosta kuvapisteitä, joiden sijainti ja väriarvo on määritelty [6]. Selvänä etuna vektorikuville on, että ne skaalautuvat todella suuriksi tai pieniksi menettämättä yksityiskohtiaan verratessa bittikarttakuviin. Kuvassa 1 pieni osa pullosta on suurennettu seitsenkertaiseksi, jolloin vektorikuvan huomattavasti parempi tarkkuus bittikarttakuvaan verrattuna voidaan havaita. Kuva 1 Vektori- ja bittikarttaesitysmuodon skaalautuvuuserot. [7] Äärettömän resoluution saavuttaminen tietokoneiden näyttötekniikassa tai tulostimien tulostustarkkuudessa on kuitenkin mahdotonta, joten 3D-mallien sekä vektorikuvien tapauksessa muodot on muutettava bittikarttamaisesti kuvapisteiksi, eli

2. Antialiasointi 4 pikseleiksi. Muuntamiseen käytetään toimenpidettä jota kutsutaan näytteistämiseksi. Näytteistämisessä korkean resoluution kuvista valitaan vain tietyt pisteet näytöllä esitettäväksi ja asetetaan kyseisten pisteiden väriarvot sekä sijainnit vakioksi, eli muodostetaan niistä bittikarttaesitys. Näytteistys tulee suorittaa myös bittikarttakuville, mutta esimerkin havainnollisuuden kannalta käsittelemme vektorikuvia. Näytteistämisessä pätee signaalinkäsittelystä tuttu Nyqvistin näytteenottoteoreema, jonka mukaan näytteistyksen taajuuden puolikasta korkeammat taajuudet laskostuvat alemmille taajuuksille [8]. Tämänkaltainen kuvan laskostuminen tunnetaan myös kuvan aliasoitumisena ja on havaittavissa selkeimmin näytteistyksen tuloksena saadun kuvan sisältämien reunojen porrastumisena. Porrastuminen voi olla erittäin häiritsevää, mikäli porrastuneen reunan eri puolien välillä on suuri kontrastiero. Myös muita aliasointiartifakteja voi ilmetä, mutta tämän työn esimerkeissä käytetään porrastumista sen havainnollisuuden vuoksi. Kuvan 2 oikeanpuolisen kolmion sekä kolmioiden välisen käyrän reunoilla voidaan huomata, etteivät viivat ole kärkipisteiden välillä suoria vaan niissä on tapahtunut porrastumista. Myös vasemmanpuolisen kolmion seinät ovat porrastuneet. Tämän havaitseminen on kuitenkin vaikeampaa, sillä 45 asteen kulman moninkerroissa suhteessa vaakatasoon olevat viivat eivät porrastu yhtä häiritsevästi kuin muut. Tämä johtuu siitä, että jokainen pikseli on porrastunut yhtä paljon edeltäjäänsä verrattuna. Kuva 2 Aliasoitumista viivojen reunoilla. Porrastumista on täten havaittavissa aina, kun viiva ei ole tarkalleen vaaka- tai pystysuora, johtuen rajatusta näyttöpisteiden lukumäärästä. Sen häiritsevyyttä voidaan kuitenkin vähentää eri menetelmin. Näiden menetelmien käyttämistä kutsutaan antialiasoinniksi ja ne voidaan jakaa kahteen pääkategoriaan, esi- ja jälkisuodatukseen, riippuen tehdäänkö suodatus ennen vai jälkeen näytteistyksen. Antialiasoinnin perusajatuksena molemmissa tapauksissa on laskea kuvan taajuus lähemmäksi näyttölaitteen Nyqvistin rajataajuutta. Käytännössä tämä tarkoittaa sitä, että kuvassa olevat reunat eivät ole yhtä teräviä, jolloin kontrastierojen pienentyessä aliasoituminen ei ole yhtä häiritsevää. Antialiasoimista kutsutaankin myös reunanpehmennykseksi.

2. Antialiasointi 5 Esisuodatuksesta kertovassa artikkelissaan [9] Chan kuvailee antialiasoinnin toteuttamista esisuodattamalla näkymästä irroitetut ääriviivat ja yhdistämällä ne ilman antialiasointia renderöityyn kuvaan. Tämä työ keskittyy antialiasointiin jälkisuodatuksen avulla. 2.2. Jälkisuodatus Toisin kuin esisuodatuksessa, jälkisuodatuksessa antialiasointi tapahtuu näytteistyksen jälkeen. Jälkisuodatustekniikassa (engl. Supersampling) jokaista lopullisen näyttötarkkuuden pikseliä kohden valitaan näytteistyksessä useampi kuin yksi piste. [10, s. 5] Näytteistyksen tarkkuus on yleisesti valittavissa kahden potenssien välein, jonka vuoksi merkinnät 2X, 4X, 8X, 16X ja 32X esiintyvät esimerkiksi pelien antialiasointiasetuksissa, riippuen grafiikkalaitteiston tuesta. Merkinnät tarkoittavat kuinka moninkertaisella tarkkuudella kuva renderöidään suhteessa näyttölaitteen resoluutioon. Esimerkiksi näyttöresoluution ollessa 1400 pikseliä vaakatasossa ja 900 pikseliä pystytasossa, näytteistetään 3D-maailman näkymä 2X-antialiasointitapauksessa kaksinkertaiseen resoluutioon 2800 pikseliä vaakatasossa ja 1800 pikseliä pystytasossa. Näytteistyksen jälkeen resoluutio pudotetaan näyttötarkkuutta vastaavaksi käyttäen useimmiten keskiarvosuodatusta ja täten jokaisen näytön pikselin väriarvo lasketaan 2X-tapauksessa neljän näytepisteen keskiarvona. Eri jälkisuodatusmenetelmiä voidaan vertailla toistensa kanssa sen perusteella, millaista algoritmia käytetään pikselikohtaisten näytteiden valitsemiseen. Näytteistysalgoritmien erojen havainnollistamista varten kuvassa 3 esitellään yhden pikselin alue kuvitteellisesta renderöintikohteesta. Kuva 3 Yhden pikselin alue renderöitävästä näkymästä. Algoritmeja havainnollistetaan kuvaan 3 lisättävien näytekuvioiden avulla. Näytekuvioista käy ilmi, mistä kohtaa pikselin aluetta näytteet otetaan renderöintiä varten. Näytteet ovat nelialkioisia vektoreita, joiden keskiarvo lasketaan alkioittain lopullisen pikselin väriarvon saamiseksi. Vektorin neljä alkiota ovat näytepisteen punainen, vihreä ja sininen komponentti, sekä pisteen läpinäkyvyyden ilmaiseva alpha-

2. Antialiasointi 6 komponentti. Seuraavaksi esitellään muutama eri algoritmi, joilla näytteistys voidaan toteuttaa. 2.2.1. Grid-algoritmi Kuvassa 4 mukaillussa Grid-algoritmissa pikseli on jaettu alipikseleihin. 2Xtapauksessa yhdellä lopullisen resoluution pikselialueella on neljä alipikselialuetta. Jokaisen alipikselialueen keskikohdasta otetaan näyte ja pikselin lopullinen väriarvo määräytyy näiden näytteiden keskiarvona. [11, s. 4 5 ] Kuva 4 Yhden pikselin tuottaminen Grid-algoritmilla. Algoritmin etuina ovat sen yksinkertaisuus ja laskentanopeus. Alipikselien määrästä riippuen antialiasointi saattaa kuitenkin jäädä vähäiseksi. [11, s. 3] Myös antialiasoinnin säännönmukaisuus saattaa olla häiritsevää. 2.2.2. Stokastinen algoritmi Kuvassa 5 mukaillussa stokastisessa algoritmissa näytteistyspisteiden sijainnit asetetaan satunnaisesti. Tämän etuna on Grid-algoritmin säännönmukaisuuden rikkominen. [12] Kuva 5 Yhden pikselin tuottaminen stokastisella algoritmilla. Satunnaisuudesta johtuen näytepisteet saattavat kuitenkin olla hyvin lähellä toisiaan. Tällöin seurauksena voi olla aliasoinnin korostuminen sekä turhaa laskentaa. [12]

2. Antialiasointi 7 2.2.3. Poisson Disc -algoritmi Kuvassa 6 mukailtu Poisson Disc -algoritmi pyrkii korjaamaan stokastisen algoritmin ongelman näytepisteiden kasautumisesta liian pienelle alueelle. Näytepisteiden valinta on satunnainen, mutta kahden pisteen välinen vähimmäisetäisyys on määritelty vakioksi. [13] Kuva 6 Yhden pikselin tuottaminen Poisson Disc -algoritmilla. Vähimmäisetäisyyden määrittäminen johtaa tasaisesti jakautuneeseen satunnaiseen näytepisteiden valintaan, mutta se on laskennallisesti liian raskas ollakseen järkevä valinta reaaliajassa tapahtuvaan renderöintiin. [12] 2.2.4. Jittered-algoritmi Kuvassa 7 mukaillussa Jittered-algoritmissa yhdistyvät Grid-, stokastinen- ja Poisson Disc -algoritmien ominaisuudet. Algoritmissa kuva jaetaan ensin Grid-algoritmin tavoin pienempiin osa-alueisiin, tämän jälkeen näytepisteet jaetaan tasan jokaisen osa-alueen sisälle satunnaisesti. Jittered-algoritmi pyrkii saavuttamaan Poisson Disc -algoritmista tutun tasaisen jakauman pikselialueen yli vähemmällä laskemisella. [10, s. 23] Kuva 7 Yhden pikselin tuottaminen Jittered-algoritmilla. Näytepisteiden kasautuminen toistensa lähelle on yhä vaarana. Se on kuitenkin huomattavasti vähemmän häiritsevää, kuin mikäli näytepisteet voisivat kasautua mihin kohtaan tahansa pikselin alueella. [10, s. 23]

2. Antialiasointi 8 2.2.5. Käännetty Grid-algoritmi Kuvassa 8 mukailtu käännetty Grid-algoritmi on Grid-algoritmin tavoin nopea laskea. Sen suurimpana etuna on, että tarkkaan pysty- ja vaakasuorat reunat antialiasoituvat vähemmän kuin Grid-algoritmin tapauksessa. Tämä johtuu siitä, että Grid-algoritmissa pysty- ja vaakasuorassa olevien reunojen molempia puolia painotetaan yhtä paljon, jolloin niitä pehmennetään aiheetta. Tarpeeton antialiasointi on myös käännetyllä algoritmilla ongelmana, mutta kääntämisestä riippuvassa kulmassa. [11, s. 9] Kuva 8 Yhden pikselin tuottaminen noin 45-astetta käännetyllä Grid-algoritmilla. Käännetyn Grid-algoritmin käyttäminen johtaa parannuksiin antialiasoinnin laadussa useissa käytännön tapauksissa, kuten peleissä esiintyvissä lampputolpissa tai portaikoissa. Grid-algoritmiin verrattaessa erot ovat kuitenkin huomaamattomia pienten kontrastierojen alueilla [11, s. 9]. 2.2.6. Adaptiivinen jälkisuodatus Jälkisuodatus vaatii grafiikkalaitteistolta paljon muistia, sillä renderöitävä kuva on moninkertainen lopulliseen kuvaan nähden. Suorituskyvyn parantamiseksi on huomioitava, että suodatusta tarvitaan vain kohdissa, joissa pikselin alueella esiintyy kaksi tai useampi eri väristä reunaa. Yhdessä näkymässä on täten monta pikseliä, jotka ovat samoja ennen ja jälkeen renderöinnin. [13] Adaptiivinen suodatus pyrkii parantamaan jälkisuodatuksen suorituskykyä tarkastelemalla näytteistettävän pikselin aluetta ennen näytepisteiden valintaa. Suodatus ottaa pikselin alueen kulmista muutaman näytteen ja arvioi niiden eroavuuksien perusteella, tuleeko kyseiseltä alueelta valita useampia näytteitä vai voidaanko alue näytteistää kulmapisteiden keskiarvona suoraa pikseliksi. Adaptiivista suodatusta voidaan käyttää riippumatta siitä, millä algoritmilla näytepisteiden valinta aiotaan toteuttaa. [13] 2.2.7. Suodatustulos Grid-algoritmilla Seuraavaksi tarkastellaan Grid-algoritmin suodatustulosta. Suodatusprosessin alussa kuva 2 muodostettaisiin uudestaan kaksinkertaiseen spatiaaliresoluutioon, mutta tässä

2. Antialiasointi 9 esimerkkiohjelmassa on lähtökohtana tilanne, jossa toimenpide on jo tehty. Tämän jälkeen kuvaan kohdistetaan alipäästösuodatus ja lopuksi se muutetaan takaisin alkuperäiseen kokoonsa. Suodatus toteutetaan MathWorks Matlab -ohjelman versiolla 7.7.0 hyödyntäen kaksiulotteisen konvoluution toteuttavaa conv2-funktiota. Funktio saa parametreinaan kaksi matriisia. Ensimmäinen matriisi sisältää tässä esimerkissä käytettävän kuvan ja toinen matriisi sisältää suotimen, jolla jokainen lopullisen kuvan pikseliarvo lasketaan. Suodin määritetään Grid-algoritmin tapauksessa seuraavanlaiseksi 4x4-matriisiksi: grid = [ 1 0 0 1; 0 0 0 0; 0 0 0 0; 1 0 0 1 ] / 4 jonka jälkeen kutsutaan conv2-funktiota aa_kuva = conv2( kuva, grid ) joka tallentaa tuloksena syntyneen matriisin muuttujaan aa_kuva. Matriisi on kuitenkin vielä kaksi kertaa halutun kuvan kokoinen, joten seuraavaksi funktio imresize skaalaa aa_kuva-matriisin lopulliseen kokoonsa, eli 0,5-kertaiseksi aa_kuva = imresize( aa_kuva, 0.5, nearest ) Kuva 9 esittää lopputuloksena syntynyttä kuvaa, jonka yksi osa on suurennettu jälkikäteen. Kuvasta voidaan huomata porrastuneisuuden väheneminen verrattaessa kuvaan 2. Kuva 9 Aliasoituneet kolmiot Grid-algoritmin jälkeen. Käännetty Grid-algoritmi olisi käsitellyt kuvan kehyksiä sekä kolmioiden alareunoja hieman paremmin, mutta silmämääräisesti arvioituna erot eivät olleet merkittäviä. Lähdekoodi matlab-kielisestä funktiosta löytyy kokonaisuudessaan liitteestä 1.

10 10 3. MICROSOFT DIRECTX 9 3.1. DirectX 9 yleisesti DirectX 9 julkaistiin ensimmäistä kertaa vuonna 2002 päivittyen vuosina 2003, 2004, 2007 ja viimeisimmän kerran vuonna 2008 versioon DirectX 9c. DirectX koostuu useasta COM-objektista, jotka ovat omia ohjelmistokokonaisuuksiaan tarjoten yhdessä kattavan ohjelmointikirjaston pelien sekä muiden multimediasovellusten tuottamiseen ja suorittamiseen [2, s. 6]. Oliopohjaisen toteutuksen ansiosta yhteensopivuus edellisten DirectX-versioiden kanssa on voitu säilyttää, joten DirectX 9 -laitteistolla on mahdollista suorittaa esimerkiksi DirectX 7 -versiota käyttäviä sovelluksia. [2, s. 5 6] Seuraavassa listassa DirectX 9:n ohjelmointirajapintojen vastuualueet lyhyesti kuvailtuna. - Direct3D: Kuvien esittäminen tietokoneen näytöllä. Rajapinnan avulla onnistuu esimerkiksi 3D-malleista koostuvien maailmoiden esittäminen sekä animointi. [14, s. 21] - DirectShow: Monien eri video- ja ääniformaattien lataaminen ja toistaminen. Tuettuihin formaatteihin kuuluvat muun muassa MPG ja MP3. [14, s. 21] DirectShow:n avulla ohjelman on myös mahdollista vastaanottaa tietoa esimerkiksi WDM-pohjaisilta laitteilta. [15] - DirectInput: Käyttäjän syötteiden vastaanottaminen tietokoneen eri oheislaitteilta, kuten hiiri, näppäimistö ja peliohjaimet. [14, s. 21] Rajapinnan avulla pystyy myös hallitsemaan esimerkiksi Force Feedback -ohjainten värinäominaisuuksia. [16] - DirectSound: Yhteys äänikorttiin. Rajapinta mahdollistaa äänien toistamisen 3D-maailmaan sekä äänien kaappaamisen eri äänityslaitteilta. [17]. - DirectPlay: Moninpelien sekä verkon yli kommunikoivien sovellusten keskinäinen tiedonsiirto. [14, s. 21] - DirectSetup: Tarvittavien DirectX-komponenttien tarkistus ja asentaminen Windows-ympäristöön. [18] Komponenttirakenteeseen kuului aikaisemmin myös erillisenä DirectDraw, joka on vastuussa kaksiulotteisten kuvien piirrosta, mutta DirectX:n versiosta 8 alkaen se yhdistettiin DirectX Graphics -nimiseen kokoonpanoon. Graphics on käytännössä Direct3D, johon on lisätty muutamia DirectDraw:n toimintoja. [3, s. 59] Tässä työssä keskitytään DirectX:n version 9c Direct3D-ohjelmointirajapintaan.

3. Microsoft DirectX 9 11 3.2. Direct3D Direct3D on DirectX:n tärkeimpiä kirjastoja graafisten sovellusten kannalta. Sen luokat ja funktiot tarjoavat sovelluskehittäjille standardoidun ja yksinkertaistetun rajapinnan kommunikointiin näytönohjaimen kanssa. Direct3D käyttää HAL:n rajapintaa (engl. Hardware Abstraction Layer), joka on laitteistotason funktioiden abstrahointikerros ja suorassa yhteydessä laitteistoajureihin [2, s. 6]. Suoran yhteyden vuoksi HAL:n toteutus on jätetty laitteistovalmistajien toteutettavaksi eikä kuulu DirectX:n vastuualueelle [2, s. 6]. Kuvassa 10 näkyvä hahmotelma arkkitehtuurista havainnollistaa Direct3D:n keskeisen aseman sovelluksien kannalta. Kuva 10: Hahmotelma näytönohjainta käyttävän sovelluksen arkkitehtuurista. Mukailtu teoksesta [2, s. 6]. Tämän työn kannalta Direct3D version 9c ominaisuuksista merkittävin on sen grafiikkaliukuhihna (engl. Graphics Pipeline). Liukuhihnan tarkoitus on tarjota tehokas tapa Direct3D-näkymien renderöimiseksi näyttölaitteelle hyödyntämällä tietokoneen laitteistoa [19]. Liukuhihnan pääpiirteet ovat nähtävissä kuvassa 11. Seuraavissa kappaleissa esitellään liukuhihnan vaiheet perustuen lähteeseen [19]. Kuva 11 Grafiikkaliukuhihnan pääpiirteet. Mukailtu lähteestä [19].

3. Microsoft DirectX 9 12 Sisäänmenoksi liukuhihna saa joukon primitiivisiä muotoja, kuten pisteitä, viivoja, kolmioita ja muita polygoneja, sekä joukon verteksejä. Tesselaatio-lohkossa muodot hajoitetaan joukoksi kolmioita, jotka tallennetaan vertekseinä verteksipuskureihin. Seuraavaksi Verteksien prosessointi -lohkossa jatketaan verteksipuskureissa olevien verteksien käsittelyä projisoimalla niiden sijaintikoordinaatit 3D-maailman koordinaatistoon. Tässä lohkossa on mahdollista määrittää käytettäväksi ohjelmoitavia verteksivarjostimia tai ennaltamäärättyä FFP-liukuhihnaa (engl. Fixed Function Pipeline) verteksien käsittelyyn. Ohjelmoitavilla varjostimilla on mahdollista muuttaa lähes kaikkia lohkon ulostuloon vaikuttavia algoritmeja, kun taas FFP-liukuhihnaa käytettäessä verteksien käsittelyalgoritmit ovat ennaltamäärätyt. Geometrian prosessointi -lohkossa vertekseihin kohdistetaan useita operaatioita, joilla Direct3D optimoi suorituskykyä ja ohjelmoijalle annetaan lisää vaikutusvaltaa verteksien käsittelyn osalta. Vertekseihin kohdistuvia operaatioita ovat muun muassa koordinaattien muuntaminen yhteiseen tasoon toistensa sekä kameran suhteen, näytettävän kuva-alueen ulkopuolelle jäävien osien poisleikkaus (engl. Clipping), objektien piiloon jäävien pintojen piirtämättä jättäminen (engl. Culling), sekä rasterointi. Piirtämättä voidaan jättää esimerkiksi ne neliön seinämät, jotka ovat piilossa muiden seinämien takana, eli joiden normaalivektorit osoittavat kamerasta poispäin. [20, s. 64 73] Seuraavaksi käsitellään tekstuurit, jotka peittävät pikseleistä koostuvat muodot. Tekstuurit ovat tietokoneen muistiin ladattavia kuvia, jotka noudetaan Direct3D:n käyttöön Teksturoitu pinta -lohkossa. Noutamisen jälkeen Tekstuurin näytteistys - lohkossa ohjelmoija voi määritellä laadun, jolla haluaa tekstuurit näytteistettävän. Tekstuurien ollessa valmiina, liukuhihna yhdistää ne aiemmin käsiteltyyn geometriseen dataan ja verteksidataan Pikselin prosessointi -lohkossa, jonka lopputuloksena saadaan pikseleiden väriarvoja. Kuten Verteksin prosessointi -lohkossa, ohjelmoija voi myös tässä lohkossa määrittää haluaako liukuhihnan käyttävän FFP:tä vai ohjelmoitavia pikselivarjostimia. Lopuksi Pikselin renderöinti -lohkossa käsitellään pikselit viimeisen kerran ennen näytöllä esittämistä. Käsittelyyn kuuluu alpha-, syvyys- sekä stencil-testaus, joissa kyseisten arvojen vaikutus lasketaan ja muunnetaan sen mukaan pikselien väriarvoja. Alpha-arvolla tarkoitetaan pikselin läpinäkyvyyttä, syvyysarvolla pikselin sijainnin kolmatta ulottuvuutta, eli z-akselia. Stencil-arvoa voidaan käyttää rajaamaan kuvaalueelle piirrettäviä pikseleitä, sitä käytetään yleensä syvyyden kanssa luomaan 3Dmalleille varjoja. 3.3. Varjostimet ja HLSL Erilaiset visuaaliset tehosteet ovat tärkeässä osassa nykyajan peleissä. Tehosteilla on mahdollista esimerkiksi saada pelimaailma lähemmin vastaamaan reaalimaailmaa. Visuaalisia tehosteita ovat muun muassa veden pinnassa tapahtuva valon taittuminen tai

3. Microsoft DirectX 9 13 eri pintojen heijastavuus. Käytettävien tehosteiden ominaisuudet riippuvat paljon sovelluskohteesta, sillä toisinaan niillä halutaan lisätä realismia ja toisinaan välttää sitä. Pelimaailman ominaisuuksien täydentämisen lisäksi toinen tärkeä päämäärä on renderöityjen näkymien virheettömyys ja laatu. Näiden päämäärien saavuttamiseksi kuvaa voidaan käsitellä erilaisilla varjostimilla (engl. Shader), jotka ovat käytännössä ohjesääntöjä sille, miten verteksejä ja pikseleitä tulee käsitellä näytönohjaimen grafiikkaliukuhihnalla. DirectX 8 -versiosta alkaen ohjelmoijien on ollut mahdollista käyttää ohjelmoitavia verteksi- ja pikselivarjostimia FFP-liukuhihnan käyttämisen sijaan. Ohjelmoitavat varjostimet tarjosivat mahdollisuuden entistä joustavampaan graafisten tehosteiden hyödyntämiseen. Nämä varjostimet ohjelmoitiin aluksi alemman tason assemblykielellä, kunnes DirectX 9 -version myötä Microsoft esitteli HLSL-kielen (engl. High- Level Shading Language). [20, s. 269] HLSL on syntaksiltaan C-kieltä muistuttava assembly-kieltä korkeamman tason kieli varjostimien ohjelmointiin. HLSL:n esittelyn myötä ohjelmoijat voivat käyttää enemmän aikaa itse varjostinalgoritmien suunnitteluun kuin niiden ohjelmointiin. Assembly-kielisiin ohjelmiin verrattaessa HLSL-ohjelmat ovat helppolukuisempia, niiden ylläpito on yksinkertaisempaa ja virheiden korjaaminen tämän vuoksi vähemmän aikaa vievää. [20, s. 269] HLSL-ohjelmakoodi voidaan kirjoittaa osaksi muun ohjelman lähdekoodia, mutta ohjelmiston modulaarisuuden kannalta parempi vaihtoehto on erotella varjostimien lähdekoodi omaan ASCII-tekstitiedostoon. Ohjelmakoodissa voidaan tällöin kutsua funktiota D3DXCompileShaderFromFile, joka kääntää tiedostossa olevan varjostimen konekielelle. [20, s. 270] Kääntämisvaiheessa tulee esille yksi HLSL-varjostinten merkittävä etu, sillä ne voidaan helposti kääntää eri verteksi- ja pikselivarjostinversioille [20, s. 279]. Tämä lisää ohjelman yhteensopivuutta, sillä uusille varjostinversioille käännetyt varjostimet ovat epäsopivia käytettäväksi vanhemmilla laitteistoilla. Varjostimien toteutus on mahdollista suojata kääntämällä lähdekoodi halutuille verteksi- ja pikselivarjostinversioille etukäteen ja julkaista ohjelman mukana vain käännetty tiedosto ilman lähdekoodia. Tämä on suosittu tapa tietokonepelien keskuudessa, sillä varjostinalgoritmien kehittämiseen on yleensä investoitu resursseja, joita ei haluta jakaa kilpailijoiden kanssa.

14 14 4. ANTIALIASOINTIVARJOSTIMEN TOTEUTUS HLSL-KIELELLÄ Toteutuksessa antialiasointisuotimen algoritmiksi valitaan Grid-algoritmi, sillä sen näytepisteiden valintaperiaate on helposti hahmotettavissa varjostimen rakenteen ollessa lopputuloksen laatua tärkeämmässä osassa työn havainnollisuuden kannalta. Varjostimen HLSL-kielinen toteutus on liitteessä 2. Seuraavassa selvitetään aluksi lyhyesti miten varjostin otetaan käyttöön ja tämän jälkeen käydään läpi itse varjostimen toimintaa. Varjostin sijoitetaan osaksi C++-kielistä ohjelmistoa, jonka vastuulla on 3Dnäkymän objektien määritteleminen ja varjostimen käyttöönotto. Objektina on tässä tapauksessa neljän verteksin määrittämä teksturoitu taso. Microsoft tarjoaa ohjelmiston kehittämiseen DirectX SDK -työkalun, jonka sisältämät esimerkkiohjelmat ovat hyvä lähtökohta DirectX-ohjelman toteutuksen tarkasteluun. Aluksi C++-kielellä toteutetussa ohjelmistossa on määriteltävä taustapuskurin kooksi kaksinkertainen esitettävän ikkunan kokoon nähden komennoilla d3dpp.backbufferwidth = WIN_WIDTH * 2 d3dpp.backbufferheight = WIN_HEIGHT * 2 joissa d3dpp on D3DPRESENT_PARAMETERS-tyyppinen muuttuja, johon ohjelmoijan tulee määrittää Direct3D-näkymän esitykseen liittyviä parametreja. Näiden parametrien käsittely jää kuitenkin tämän työn ulkopuolelle. Taustapuskuri on grafiikkaliukuhihnan käyttämä aputaso, johon näkymä renderöidään ennen näytöllä esittämistä. Taustapuskurin koko määritellään kaksinkertaiseksi, sillä toteutettavan ohjelman on tarkoitus suorittaa antialiasointi 2X-menetelmällä. HLSL-kielestä assembly-kieleen käännetty varjostin otetaan käyttöön C++-koodissa komennolla d3ddev->setpixelshader( pixelshader ) jonka kutsumisen jälkeen pixelshader-osoittimeen tallennettu varjostin on asetettu osaksi Direct3D:n grafiikkaliukuhihnaa ja jokainen renderöitävä pikseli kulkee määritellyn varjostimen läpi. Funktiokutsussa käytetty LPDIRECT3DDEVICE9- tyyppinen d3ddev-osoitin osoittaa aiemmin ohjelmassa alustetun Direct3D-laitteen luokkaan.

4. Antialiasointivarjostimen toteutus HLSL-kielellä 15 Varjostimelle asetetaan kaksi globaalia vakiota ennen käyttöönottoa, WIDTH_POS ja HEIGHT_POS, jotka sisältävät tiedon DirectX-ikkunassa olevien pikselien välisestä etäisyydestä leveys ja korkeussuunnassa. Laskutoimenpiteet näitä vakioita varten on toteutettu ohjelman C++-puolella, käytännössä ne ovat esitysikkunan leveyden ja korkeuden käänteislukuja. Seuraavaksi määritetään PS_INPUT tietorakenne, joka määrittelee varjostimen sisääntulon. Muuttujien määrittelyssä kaksoispisteiden vasemmalla puolella on varjostimessa käytettävän muuttujan tyyppi ja nimi, ja oikealla puolella rekisteri, josta sijainnit, tekstuurikoordinaatit sekä väriarvot haetaan. Arvot ovat tallennettuna käytettäviin rekistereihin verteksivarjostimen toimesta. Liukulukumuuttujista Position sisältää käsiteltävän pikselin sijainnin, Texture tekstuurin koordinaatin ja Color pikselin värin sekä läpinäkyvyyden. Sisääntulon jälkeen määritellään vastaavaan tapaan ulostulolle tietorakenne, joka koostuu vain väriarvon ilmoittavasta liukulukumuuttujasta Color. Ulostulona varjostimella on täten yksi pikseli, joka sisältää väriarvon ja läpinäkyvyyden. Näiden tietorakenteiden alustamisen jälkeen alustetaan vielä globaali näytteistäjäobjekti tex0, jota tarvitaan myöhemmin tekstuurien näytteistyksessä käytettävän funktion parametrina. Näiden alustuksien jälkeen alkaa itse pääohjelman määrittäminen. Pääohjelman sisääntulo määritetään PS_INPUT tyyppiseksi muuttujaksi In ja pääohjelman paluuarvo PS_OUTPUT-tyyppiseksi Out-muuttujaksi. Pääohjelman alussa alustetaan nelialkioinen liukulukutaulukko kuvaamaan 2x2-matriisia, jota käytetään tekstuurin koordinaattien määrittelyyn. Tämän taulukon avulla voidaan siirtää tekstuurin indeksointia näyttöresoluution pikselin puolikkaan verran viistoon. Taulukon määrittelyn jälkeen tekstuuri näytteistetään tex2d-funktiolla. Näytteistys tapahtuu ottamalla for-silmukan sisällä neljä näytettä tekstuurina käytettävän kuvan eri kohdista. Tekstuuri on määritelty ohjelman C++-osassa. Parametreina tex2d tarvitsee näytteistäjäolion sekä tekstuurin koordinaatin. Koordinaatiksi annetaan sisääntullut x- ja y-koordinaatti, joihin lisätään aiemmin alustetusta taulukosta arvo. Tämän seurauksena näytteistyspistettä on siirretty näytteistettävän pikselin alueen sisällä pois keskikohdasta lähemmäs reunoja. Funktio tex2d-palauttaa valitusta tekstuurin kohdasta vektorin, joka sisältää näytteen väriarvon sekä läpinäkyvyyden. Näytevektorit tallennetaan nelialkioiseksi alustettuun neighboursliukulukutaulukkoon. Seuraavaksi lasketaan niiden keskiarvo avg-muuttujaan ja lopuksi asetetaan ulostulon pikselin arvoksi saatu keskiarvo ja palautetaan näin valmistunut muuttuja Out, jolloin yhden pikselin alueen käsittely on valmis. Kuvassa 12 on vertailun vuoksi osa ilman kuvattua varjostinta tuotettua 3Dnäkymää ja kuvassa 13 puolestaan sama näkymä on tuotettu yllä luodun varjostimen avulla. Verrattaessa näitä kahta toisiinsa, voidaan havaita antialiasoinnin tuottama reunanpehmennys viivojen reunoilla. Kuvasta 13 voidaan myös havaita etenkin kaukaisimpien viivojen esityslaadun paraneminen.

4. Antialiasointivarjostimen toteutus HLSL-kielellä 16 Kuva 12 Näkymä kolmiulotteisesta tasosta ilman toteutettua pikselisuodinta Kuva 13 Näkymä kolmiulotteisesta tasosta toteutetun pikselisuotimen kanssa Esimerkkivarjostin suoritetaan kokonaisuudessaan jokaiselle kuvan pikselille, vaikka näin ei olisi tarpeen tehdä muualla kuin reunojen lähettyvillä. Varjostimen parantamiseen esitettiin luvussa 2.2.6 adaptiivinen suodatus, joka parantaisi tämän esimerkkitoteutuksen antialiasoinnin laatua. Se käyttäisi tarkempaa antialiasointia viivojen reunoilla ja jättäisi viivojen keskiosat sekä niiden väliset mustat alueet antialiasoinnin ulkopuolelle. Adaptiivisen suotimen toteuttaminen jää kuitenkin tämän työn ulkopuolelle, sillä se hankaloittaisi työssä käytetyn suotimen hahmottamista yksityiskohdillaan.

17 17 5. JOHTOPÄÄTÖKSET Microsoft DirectX on suuri kokonaisuus, joka sisältää kokonaisvaltaisen komponenttivalikoiman multimediasovellusten hallintaan. Työssä esiteltiin DirectX - tekniikan versio 9c varsin korkealta tasolta käyden läpi sen syntyhistoria ja listaamalla sen sisältämät komponentit. Tietokonegrafiikan jatkuva pyrkimys visuaalisesti parempiin lopputuloksiin todettiin tärkeäksi ja syvennyttiin antialiasointitekniikkaan nimeltä jälkisuodatus. Jälkisuodatuksesta esiteltiin teoriassa äärettömään resoluutioon skaalautuvan vektorigrafiikan avulla. Suuri resoluutio johtaa näyttölaitteen resoluution riittämättömyyteen, joka taas ilmentyy aliasoitumisesta johtuvien porrastumisartifaktien muodostumisena. Työssä käytiin läpi porrastumiseen johtavat syyt sekä jälkisuodatustekniikka ratkaisuna sen vähentämiseksi. Jälkisuodatuksen todettiin olevan yksinkertainen ja tehokas, mutta suorituskyvyllisesti haastava toteutustapa verrattuna esisuodatusta käyttäviin menetelmiin. Graafisissa sovelluksissa Direct3D-komponentin keskeisen aseman vuoksi se käsiteltiin muita DirectX-tekniikan osia tarkemmin. Tarkoituksena oli selvittää lukijalle miten kolmiulotteisten mallien käsittely etenee grafiikkaliukuhihnalla joukosta verteksejä joukoksi pikseleitä. Direct3D on itsessään todella laaja kokonaisuus, joten työssä ei syvennytty sen grafiikkaliukuhihnan jokaisen komponentin toimintaan yksityiskohtaisesti. Tietokonegrafiikkaan liittyy läheisesti myös verteksi- ja pikselivarjostimien käyttäminen. Varjostimet voitiin todeta lähes välttämättömyydeksi graafisesti korkealuokkaisien 3D-maailmojen tarjoamisen kannalta. Työssä käytiin läpi niiden merkityksen lisäksi ohjelmointikielen asema niitä suunniteltaessa. DirectX-tekniikan versiosta 9 lähtien varjostimia on ollut mahdollista toteuttaa HLSL-kielellä, joka on C- kieltä muistuttava assemblya korkeamman tason ohjelmointikieli. Työssä esiteltiin HLSL-kielen tuomat hyödyt laitteistoläheiseen assembly-kieleen verrattuna sekä toteutettiin antialiasoiva pikselivarjostin. Toteutuksen yhteydessä todettiin varjostimen toimintaa voitavan parantaa käyttämällä adaptiivista suodatusta. Suodatustuloksista voidaan havaita antialiasoinnin tehokkuus etenkin kaukaisien viivojen tapauksessa. Vaikka porrastuminen ei esimerkkikuvissa ole kovin suurta, sen häiritsevyys lisääntyy oleellisesti kun näkymä asetetaan liikkeeseen.

18 18 LÄHTEET [1] Sanches, J., Canton M.P. The PC Graphics Handbook. 2003, CRC Press. 1006 p. [2] Jones, W. Beginning DirectX 9. 2004, Premier Press. 353 p. [3] Walsh, P. Advanced 3D Game Programming Using DirectX 9.0. Plano, Texas 2003, Wordware Publishing. 514 p. [4] Glassenberg, S. Introduction to Direct3D 10 (SIGGRAPH 2007) [WWW]. 5.8.2007 [viitattu 29.4.2009] Saatavissa: http://www.microsoft.com/downloads/details.aspx? FamilyID=96cd28d5-4c15-475e-a2dc-1d37f67fa6cd&DisplayLang=en. [5] Lilley, C., Schepers, D. Scalable Vector Graphics (SVG) [WWW]. 15.4.2009 [viitattu 30.4.2009]. Saatavissa: http://www.w3.org/graphics/svg/. [6] Bourke, P. BMP Image Format [WWW]. 1998 [viitattu 11.4.2009]. Saatavissa: http://local.wasp.uwa.edu.au/~pbourke/dataformats/bmp/. [7] Vector Bitmap Example. 27.6.2007 [viitattu 27.4.2009]. Saatavissa: http://en.wikipedia.org/wiki/file:vectorbitmapexample.png. [8] Gonzalez, R., Woods, R. Digital Image Processing. 3. 2007, Prentice Hall. 976 p. [9] Chan, E. Fast Antialiasing Using Prefiltered Lines on Graphics Hardware [WWW]. 1.3.2004 [viitattu 16.4.2009]. Saatavissa: http://graphics.csail.mit.edu/~ericchan/articles/prefilter/. [10] Goss, M., Wu, K. Study of Supersampling Methods for Computer Graphics Hardware Antialiasing [WWW]. Palo Alto, California, Hewlett-Packard Laboratories. 2000 [viitattu 30.4.2009]. Saatavissa: http://www.hpl.hp.com/techreports/1999/hpl- 1999-121R1.html. [11] Beets, K., Barron, D. Super-sampling Anti-aliasing Analyzed [WWW]. 2000 [viitattu 30.4.2009]. Saatavissa: http://onversity.com/doc/fsaa.pdf. [12] Wei, L-Y. Parallel Poisson Disk Sampling [WWW]. 2008 [viitattu 30.4.2009]. Association for Computing Machinery, Inc. Saatavissa: http://research.microsoft.com/apps/pubs/default.aspx?id=70563.

Lähteet 19 [13] Genetti, J., Gordon, D. Ray Tracing With Adaptive Supersampling in Object Space [WWW]. 1993 [viitattu 2.5.2009]. Saatavissa: http://www.cs.uaf.edu/~genetti/research/papers/gi93/gi.html. [14] Thorn, A. DirectX 9 Graphics: The Definitive Guide to Direct 3D. Plano, Texas 2005. Wordware Publishing. 500 p. [15] DirectShow System Overview [WWW]. [viitattu 11.4. 2009]. Microsoft Corporation. Saatavissa: http://msdn.microsoft.com/en-us/library/ms783354.aspx. [16] Introduction to DirectInput [WWW]. [viitattu 11.4. 2009]. Microsoft Corporation. Saatavissa: http://msdn.microsoft.com/en-us/library/bb174606(vs.85).aspx. [17] DirectSound Interfaces [WWW]. [viitattu 11.4.2009]. Microsoft Corporation. Saatavissa: http://msdn.microsoft.com/en-us/library/bb219821(vs.85).aspx. [18] Installing DirectX with DirectSetup [WWW]. [viitattu 11.4.2009]. Microsoft Corporation. Saatavissa: http://msdn.microsoft.com/en-us/library/bb174600.aspx. [19] Direct3D Architecture (Direct3D 9) [WWW]. [viitattu 11.4.2009]. Microsoft Corporation. Saatavissa: http://msdn.microsoft.com/en-us/library/bb219679.aspx. [20] Luna, F. Introduction to 3D game programming with DirectX 9.0. Plano, Texas 2003. Wordware Publishing. 400 p.

20 20 LIITE 1: MATLAB-TOTEUTUS % Funktiota kutsutaan nimellä antialiasointi ja % se saa parametrinaan antialiasoitavan kuvan. % Ulostuloksi funktio antaa antialiasoinnin tuloksen. function[ kuva_grid ] = antialiasointi(kuva) % Ladataan kuva kuva = uint8( imread( kuva ) ); % Määritetään matriisi n, joka valitsee kuvasta % näytteistyspisteet n = [ 1 0 0 1; 0 0 0 0; 0 0 0 0; 1 0 0 1 ]; % Suoritetaan konvoluutio Grid-algoritmilla jokaisella % kuvan värikanavalla for v = 1:size(kuva,3) kuva_grid(:,:,v) = conv2( kuva(:,:,v), n ) / 4; end % Lasketaan kuvan koko puoleen kuva_grid = uint8( imresize( kuva_grid, 0.5,'nearest' ) ); % Myös alkuperäisen kuvan koko vertailua varten kuva_alkup = imresize( kuva, 0.5,'nearest' ); % Näytetään kuvat % aluksi alkuperäinen kuva figure(); subplot(2,1,1); imshow( kuva_alkup,[] ); title( 'Antialiasoitava kuva','fontsize',14 ); % ja lopuksi antialiasoitu kuva subplot(2,1,2); imshow( kuva_grid,[] ); title( 'Antialiasoinnin tulos: Grid','Fontsize',14 );

21 21 LIITE 2: HLSL-TOTEUTUS // Globaalit vakiot, jotka asetetaan // varjostimen isäntäohjelmassa sisältämään // kahden pikselin välimatkan puolikkaan. const float WIDTH_POS; const float HEIGHT_POS; // Pikselivarjostimen sisäänmenon määrittely. struct PS_INPUT { // Määritetään sisääntulevalle datalle // parametrit sijainti, tekstuurikoordinaatti // sekä väri. Kaksoispisteen oikealla puolella // määritetään halutun datan lähde. float4 Position : POSITION; float2 Texture : TEXCOORD0; float4 Color : COLOR0; }; // Pikselivarjostimen ulostulon määrittely struct PS_OUTPUT { // Määritetään ulostulolle parametri Vari, // joka tulee sisältämään pikselin värin float4 Color : COLOR0; }; // Alustetaan globaali näytteistäjä-objekti tex0 sampler2d tex0; PS_OUTPUT main( in PS_INPUT In ) { // Luodaan ulostulopikseli PS_OUTPUT Out; // Neljä näytepistettä const int NUM = 4; // Määritetään 2x2 matriisi jota käytetään // tekstuurin sijainnin indeksoinnissa const float2 c[num] = { float2( -WIDTH_POS, HEIGHT_POS ), float2( WIDTH_POS, HEIGHT_POS ), float2( -WIDTH_POS, -HEIGHT_POS ), float2( WIDTH_POS, -HEIGHT_POS ), };

Liite 2: HLSL-toteutus 22 // Alustetaan taulukko neighbours johon kerätään // tekstuurista otetut näytteet float4 neighbours[num]; // Näytteiden keräys for( int i = 0; i < NUM; i++ ) { // Funktio tex2d palauttaa tekstuurin arvon // toisena parametrina annetusta kohdasta, // jossa hyödynnetään edelläluotua taulukkoa neighbours[i] = tex2d( tex0, In.Texture.xy + c[i] ); } // Alustetaan keskiarvomuuttuja avg float4 avg = {0.0,0.0,0.0,0.0}; for( i = 0; i < NUM; i++ ) { // Lisätään keskiarvomuuttujaan pikselin // naapurustosta kerätyt arvot avg += neighbours[i]; } // Luodaan keskiarvo avg = avg / NUM; // Asetetaan ulostulopikselin väriksi sen // naapurustosta laskettu keskiarvo Out.Color = avg; } // Palautetaan ulostulopikseli return Out;