5. Silmaring: Arvutigraafika
Autor: Raimond Tunnel, illustratsioonid: Kristel Sergo. (Materjal on lühendatud kursuse autorite poolt.)
Informaatikas on arvutigraafika väga lai valdkond, millel on omakorda palju spetsialiseerumisvõimalusi. Rääkides arvutigraafikast, mõtleme me valdkonda, mis tegeleb arvutis näha soovitava pildi genereerimisega. Selleks võib olla näiteks nupp või tekst, kuid samas ka erinevad efektid filmides ning loomulikult kogu 3D mängude visuaalne pool.
Vastavalt olukorrale tuleb arvutis graafika joonistamiseks mõelda erinevatele asjadele. Näiteks nupu korral on oluline:
- Kuhu me nupu ekraanil joonistame?
- Kas nupul on piirjoon? Kui lai? Kuidas see joonistatakse?
- Kuidas nupu sees olev tekst joonistada?
- Kas nupp on läbipaistev? Kas nupu taga on veel midagi?
Kaks küsimust nendest küsivad "kuidas" ja see ongi põhiline arvutigraafika eesmärk:
- Defineerida kuidas midagi jõuab meie programmist ekraanile.
Lahendus sellele küsimusele peab olema ka üpriski kiire. Ainuüksi käesoleval lehel on meil tuhandeid tähemärke, igal tähemärgil on mitmeid jooni ning vastavalt teksti suurusele täidavad need jooned mingi arvu piksleid.
- Piksel - ekraanipunkt, minimaalne värvitav element ekraanil (või digitaalsel pildil).
Arvutigraafikas peab vastama küsimusele, kuidas leitakse üles ning värvitakse sobiva värviga õiged pikslid ja seda näiteks 30 korda sekundi jooksul, kui kasutaja lehekülge vertikaalselt liigutab.
Arvutigraafika valdkonnal on ühisosa ka näiteks digitaalse pilditöötluse valdkonnaga. Viimane nimelt uurib, kuidas muuta olemasolevaid pilte (näiteks fotosid) paremini nähtavateks (nii inimese kui ka arvuti jaoks). Digitaalse pilditöötluse valdkonda jääb ka olemasolevate piltide pealt kujundite tuvastus. Näiteks võib arvuti programmeerida satelliitpildi pealt üles leidma autosid.
Ühisosa arvutigraafika valdkonnaga tekib olukorras, kus me tahame ühe korra joonistatud pildi peale lisada mingit efekti, et lõpptulemus oleks veelgi parem. Selliseid olukordi juhtub päris palju, kõige lihtsam näide oleks 3D mängust, kus me soovime kõike värve muuta näiteks natukene kollasemaks, sest mängul peab olema just säärane stiil. Selleks me leiame, kuidas meie 3D mängu kaader näeks välja tavaliselt ja seejärel muudame pikslite värve vastavalt.
Sissejuhatuses kirjeldatud pikslite värvi järgi millegi joonistamine on rastergraafika. Mõiste "raster" tähendab antud kontekstis pikslite ruudustikku.
Tänapäeval oleme harjunud, et arvutimonitoril olev pilt koosneb pikslitest ning sellest lähtuvalt võime kutsuda monitori ka rastermonitoriks.
Võib ette kujutada ruudulise vihiku lehte, kus värvime erinevad ruudud erinevat värvi. Igal pikslil on ka selles ruudustikus oma koordinaat.
Näiteks, kui alustame lehe ülevalt vasakult nurgast, siis allapoole jäävad pikslite read ja paremale pikslite tulbad. Võime read ja tulbad nummerdada ja kui me alustame mõlema nummerdusega 0-st, siis esimese ruudu koordinaat on (0, 0). Sellest paremal asub (0, 1) ja all asub (1, 0). Seega esimene arv tähistab rea numbrit ja teine tulba oma.
Tihtipeale aga me tahame defineerida konkreetseid geomeetrilisi kujundeid. Näiteks ruutu on rastergraafikas võimalik küll joonistada nii, et defineerime 5 pikslit paremale, 4 alla, 4 vasakule ja 4 ülesse tagasi. See on aga päris tüütu ja pigem tahaksime ruudu defineerida näiteks ainult tema küljepikkuse ja keskpunkti koordinaadiga. Näiteks olgu ruudu küljepikkus 5 ja keskpunkt näiteks koordinaadil (3, 3). Niimoodi me saame küljepikkust muuta ja lihtsasti defineerida erineva suurusega ruute. Võime muuta ka ruudu keskpunkti koordinaati ja selle läbi kujundit liigutada. Selliselt joonistatava geomeetria defineerimist nimetatakse vektorgraafikaks.
Ajalooliselt olid näiteks ühed esimesed monitorid vektormonitorid, mis joonistasid ekraanile ainult jooni ja neil puudus pikslite ruudustik.
Vektorgraafika on tänapäeval väga oluline, sest
- ekraanide mõõtmed on erinevad ja
- see võimaldab lihtsasti objektide suurust muuta.
Hea näide sellest on kirjastiilid ehk fondid. Ilmselt me tahame teksti joonistada erineva suurusega. Seda saab näha ka siis, kui me näiteks käesolevat veebilehte suurendame või vähendame (Ctrl klahv + hiire rullik edasi / tagasi). Selle tegevuse tulemusena tähed muutuvad suuremaks ja väiksemaks, kuid on iga kord samasuguse ja sujuva kujuga. Kui me oleksime teinud tähe “a” rastergraafikaga, siis suurendamise korral see täht kaotaks oma kuju.
Eelneval pildil vasakul on näha täht "a", millest tegime ekraanipildi ja suurendasime seda 100 korda. Selle tulemusena näeme suurendatud piksleid. Kusjuures kõik pikslid ei ole mustad. Sellel on ka väga hea põhjendus arvutigraafika valdkonnast. Paremal on aga sama täht "a", kuid oleme kirjasuuruse muutnud 100 korda suuremaks ja siis teinud pildi. On näha, et tähe suurendades pigem ootaksime parempoolset tulemust. Kõik tähed on aga defineeritud erinevate geomeetriliste valemitega ja seega on arvutil neid väga lihtne vastavalt vajadusele suurendada ja vähendada.
Kindlasti tekib küsimus, et kui me defineerime kujundid vektorgraafikas, kuid monitorid on rastergraafikas (koosnevad pikslite ruudustikust), siis kuidas me saame ühest teise?
Sellise tegevuse nimi on rasteriseerimine ja ka see on üks arvutigraafika eesmärke.
Üks lihtne viis selleks on panna enda geomeetriline ruum ja ruudustik kohakuti ning seejärel iga ruudu korral vaadata, kas selle ruudu alla jääb piisavalt suur osa geomeetrilisest kujundist. Kui jääb, siis saab vastava ruudu värvida näiteks mustaks. Vaata ka ingliskeelset videoselgitust kolmnurga rasteriseerimise kohta: https://www.youtube.com/watch?v=aweqeMxDnu4&feature=youtu.be&t=5m34s
Tihti on ongi vaja defineerida asju ka rastergraafikas. Näiteks kõiksugused fotod (n. JPG formaadis) just sellisel kujul ongi. Samuti kui me digimaalime pildi mõnes pilditöötlusprogrammis (nt Photoshop), siis ka see on salvestatud raster-kujul. Nimelt fotodes ja digimaalides on tihti väga keerulised kujundid, mida geomeetriliselt hoida ei ole mõtet või on isegi võimatu. Võib ette kujutada, et kui me teeme foto enda kassist, siis me ei leia kassi täielikku geomeetriat ning ei saa pärast arvutis kassi pilti lõpmatuseni detailselt suurendada. Ainus parameeter selle pildifaili juures on meil see, kui suure ruudustiku peale me kassi jäädvustasime.
Juhul kui on soov teha firmale logo, siis tuleks see teha vektorgraafikas- suuremalt ja väiksemalt särkidele ja reklaamlplakatitele trükkides jääb see alati terav. Küll aga kui on soov näiteks printida t-särgile fotot, siis on ainsaks võimaluseks kasutada pilti rastergraafikas.
3D ARVUTIGRAAFIKA
Suur osa arvutigraafikast tegeleb justnimelt 3D graafikaga, millega paljud on tuttavad nii filmidest kui arvutimängudest. See on väga suur valdkond, mille jaoks on ülikoolides tihti eraldi erialad. Samuti on see ka valdkond, kus tehakse palju koostööd 3D kunstnikega. Erinevad kolmemõõtmelised kujudid nagu kuup ja silinder on küll toredad, kuid filmis või mängus oodatakse pigem päris maailma meenutavaid ruume, esemeid ja tegelasi. Nende keerulisemate objektide geomeetriat, värve ja ka liikumisanimatsioone valmistavadki 3D kunstnikud.
Informaatika seisukohast on oluline, et defineeritud geomeetria jõuaks kiiresti ja õigesti ekraanile, objektid peegeldaksid valgust vastavalt enda värvile ja materjali omadustele. Näiteks metallid ja dielektrik materjalid peegeldavad valgust väga erinevalt. Samuti tegelevad informaatikud sellega, et joonistada erinevaid efekte nagu tuli, suits, vihm või udu.
Kogu selle töö käigus kasutatakse programmeerimises palju matemaatilisi objekte ja funktsioone: vektoreid, maatrikseid, nurga koosinust, vektorite skalaar- ja vektorkorrutist, tuletist ja integraali.
Selle kursuse raames me väga sügavuti arvutigraafika matemaatikasse ei lähe. Küll aga huvilistel on võimalus selle kohta lugeda näiteks inglise keelsest materjalist keskkonnas CGLearn.
Oleme avastanud, et ekraani peal olevad pikslid on ruudustikus ning igaühel nendest on oma värv. Kuidas aga seda värvi arvutis hoitakse?
Optikast teame, et valgusel on olemas lainepikkus. Bioloogiast teame, et inimese silmas on 3 erinevat retseptorit (kolvikesed), mis reageerivad kõige rohkem punasele, rohelisele ja sinisele valgusele. Erinev kombinatsioon nende kolme retseptori impulsist võimaldab meil tajuda erineva lainepikkusega footoneid ja värve.
Sellest inimeste bioloogilisest omapärast (lindudel on näiteks 4 erinevat tüüpi kolvikest) on disainitud ka meie ekraanid. Monitor kiirgab iga piksli kohta nii punast, rohelist kui sinist valgust. Kombinatsioon nendest kolmest erineva värvusega valgusest võimaldab meil näha erinevaid värve.
Tasub tähele panna, et erineva värvusega valguste koos kiirgamine töötab teistmoodi kui näiteks erinevate guaššvärvide segamine.
Kui meie silm tuvastab korraga punast, rohelist kui ka sinist valgust, siis kõik kolvikesed saadavad impulssi edasi ja me näeme valget värvi. Samas, kui me punase, rohelise ja sinise guaššvärvi kokku segame, siis saame tumepruuni värvi. Guaššvärvide segamisel me segame kokku erinevad materjalid, milles neelduvad erinevad lainepikkused. Mida rohkem selliseid materjale me kokku segame, seda rohkemaid lainepikkusi segu neelab ja lõpuks neeldub seal enamik nähtavast valgusest. Samas erineva värvusega valguste kiirgamisel jõuab lõpuks meie silma rohkem erinevaid lainepikkusi.
Siinkohal olekski oluline teada kahte mõistet:
Värvimudel – kuidas me tähistame arvutis erinevaid värve.
Värviruum – millistele reaalsetele värvidele meie arvutis tähistatud värvid vastavad.
RGB värvimudel ja sRGB värviruum
Kuna monitorid kiirgavad iga piksli kohta eraldi punast (red), rohelist (green) ja sinist (blue) värvi, siis kõige loogilisem variant arvutis värvi hoida olekski arvude kolmikuna, kus on kirjas nende kolme värvi intensiivsus. Sellist värvimudelit kutsutakse värvide inglise keelsete nimetuste esitähtede järgi RGB värvimudeliks.
Vastavalt olukorrale võime võtta neid arve
- ujukomaarvudena vahemikust [0, 1] või
- täisarvudena vahemikust [0, 255].
Värvide esitamine ujukomaarvudena
Esimesel juhul võime mõelda igast komponendist kui protsendist, kui palju maksimaalsest peab vastavat värvi kiirgama konkreetse piksli sees. Näiteks kolmik (1, 0, 0) tähendaks, et piksel peab olema maksimaalselt punane ja rohelist ning sinist värvi ei kiirga üldse. Kolmik (0.5, 0.5, 0) tähendaks sellisel juhul, et punast ja rohelist on vaja kiirata 50% ning sinist mitte üldse. Selline kolmik annaks meile tumekollase värvi. Tegelikkuses aga, kui me saadame sellise kolmiku monitorile, siis on meie piksel tumedam kui õige 50% kollane, mida monitor näidata suudaks. See on nii selle pärast, et nii ajaloolistel kui ka praktilistel põhjustel saadab monitor kõik värvid läbi funktsiooni tulemus =värv astmelγ, kus kreeka täht γ (gamma) võib olla erinevatel monitoridel erineva väärtusega.
Üldiselt on hea arvestada γ väärtuseks umbes 2,2 (vaata ka näiteks: http://epaperpress.com/monitorcal/gamma.html). Antud funktsioon astendab kõik arvud meie kolmikus astendajaga γ ja kuna meie arvud on vahemikust [0, 1], siis nende väärtused muutuvad väiksemateks. Selle probleemi lahendamiseks tuleks otse monitorile saadetav väärtus enne ise astendada γ pöördväärtusega 1/γ.
Värvide esitamine täisarvudena
Vaatame korraks ka eelnevalt mainitud vahemikku [0, 255] värvikanalite väärtuste jaoks. Sellel vahemikul on mitu põhjust. Esiteks, kuna arvutid hoiavad erinevaid väärtusi binaar- ehk kahendsüsteemis, siis on väärtuste hoidmiseks vahemikust [0, 255] vajalik vähem mälu. Nimelt kahendsüsteemis hoitakse kõiki väärtusi 0-de ja 1-de kombinatsioonidena ja kui meil on kaheksa kohta arvude 0 või 1 jaoks, siis on meil võimalik kujutada kõiki väärtusi [0, 255], kuid mitte midagi rohkemat (vaata ka videot https://www.youtube.com/watch?v=UBX2QQHlQ_I).
Teine põhjus on, et inimesele on rohkem loetavam (100, 140, 0) kui (0.3922, 0.5490, 0). Kusjuures paljudes kohtades kasutatakse ka heksadetsimaal- ehk kuueteistkümnendsüsteemi. Tolles süsteemis on meil lisaks tavalistele numbritele 0, 1, 2, 3, 4, 5, 6, 7, 8 ja 9 ka veel juures numbrid A, B, C, D, E ja F. Ülal toodud näide kuueteistkümnendsüsteemis oleks (64, 8C, 0). Kõige suurem arv, mida me kahe sümboliga kuueteistkümnendsüsteemis kujutada saame ongi kümnendsüsteemi 255, mis kirjutatakse FF. Veebilehtede arenduses kasutatakse justnimelt seda süsteemi värvide defineerimiseks ning seal kirjutatakse meie kolmik trellide sümboli järele järjest: #648C00.
Laiem küsimus on see, et mis värve ikkagi meie RGB või ka mõni teine värvimudel kujutab ehk millisele värviruumile ta vastab. Värvide nägemise ulatus inimestel on suurem kui see, mida monitorid suudavad väljastada. Ei ole pragmaatiline teha sellist monitori, mis suudaks näidata kõiki nähtava spektri (valguse lainepikkuste) värve. Parempoolsel joonisel kolmnurga sees on kõik värvid, mis on kujutatud enimlevinud sRGB värviruumis. Terve suurem kujund on kogu värvide nägemisulatus inimestel.