streda 4. mája 2011

Prvý generátor je na svete

Po dlhšej odmlke sa znova ozývam s blogovým príspevkom k bakalárke a napriek tomu že blogu som sa dlhšie nevenovala, na bakalárke som neprestala pracovať.
Aplikácia sa dočkala viacerých zmien, v prvom rade by som spomenula oddelenie generátorov do samostatných tried, čo mi uľahčí pridávanie rôznych generátorov do jedného programu. Filozofia tejto "reštrukturalizácie" je postavená na triede TerrainShader, ktorá obsahuje vlastný shader program a sama si obsluhuje gernerovanie výškovej mapy do textúry (princíp som odkukala z blogu Davida Coppola http://www.m3xbox.com/ ktorý písal diplomovku o terénoch). Od tejto triedy sú/budú odvodené všetky ostatné generátory, pričom ich inštancie bude mať aplikácia uložené v dynamickom poli typu vector, skade bude podľa potreby vykresľovať terény na obrazovku.
Pridané bolo ovládanie myšou, rotujúci terén je minulosťou a v súčasnej verzii si užívateľ môže terén otáčať podľa potreby stlačením pravého tlačítka a súčasným pohybom myši, takisto si môže terén priblížiť alebo oddialiť kolieskom myši. Multiplatformovosť som definitívne vyriešila použitím knižnice GLEW, podarilo sa mi projekt skompilovať aj pod Linuxom aj keď primárne programujem vo Windows. Inštalácia bola skúškou trpezlivosti, slabou útechou mi je lepšie pochopenie ako funguje linkovanie knižníc pri kompilácii.
Aplikácia už obsahuje aj prvý generátor terénu a síce jednoduchý Voronoiov diagram. Ako možno vidieť zo screenshotu budem musieť upraviť spôsob generovania náhodných čísel, pretože zjavne preferuje nižšie hodnoty oproti vyšším a tým pádom sú na jednej polovici skoro všetky klastre pričom na druhej skoro žiadne. Výsledok je však uspokojivý, doladiť ešte bude treba vizualizáciu - zvolená farebná škála zo zelenej do šedej je málo výrazná a neodlišuje dostatočne výškové rozdiely.
Voronoiov diagram vo forme terénu, generovaný a tieňovaný v GLSL
Za zmienku ešte stojí spôsob akým posiela aplikácia shaderu parametre. Aj keď je možné cez volanie glUniform*() posielať ako uniformný parameter aj pole, musí mať pevne danú veľkosť. Teda nie je prípustné napísať niečo na spôsob :

uniform int clusters;
uniform vec2 body[clusters];

pretože hodnota parametra clusters nie je vopred známa. Preto súradnice stredových bodov jednotlivých klastrov posielam v malej šedotónovej textúre veľkosti 2*počet_bodov, ktorú si vygenerujem run-time v aplikácii.
Veľkou pomocou pri programovaní v GLSL sa ukázal vývojový nástroj RenderMonkey od firmy ATI, bohužiaľ však už ukončili podporu a tak sa mi podarilo zohnať len zastaranú verziu. Super možnosťou je "live" náhľad pri zmene parametrov, takisto veľmi jednoducho sa do shadera pripojí textúra a tak sa programátor môže sústrediť plne na vývoj shadera.
Jeden generátor je vzhľadom na zostávajúci čas do odovzdania málo, mám však na to dobrý dôvod. V súvislosti so skúmaním využitia porovnávaných metód v real-time aplikáciách mi školiteľ navrhol porovnať koľko je teoreticky možné ušetriť programovaním na grafickej karte. Kvôli tomu som si posledné týždne študovala knižku An Introduction to Parallel Algorithms, kde je navrhnutý teoretický model počítača s n paralelnými procesormi so zdieľanou pamaťou pod názvom PRAM, ktorý je veľmi podobný grafickej karte s viacerými procesormi. Efektivita algoritmu sa dá potom posúdiť pomerom algoritmickej zložitosti algoritmu pre n procesorov k algoritmickej zložitosti jednoprocesorového algoritmu. Pre úplnosť je ešte možné porovnávať so zložitosťou algoritmu pre celulárny automat, čo je iný model paralelného počítača, ktorý sa líši od PRAM hlavne tým, že jednotlivé výpočtové "bunky" (t.j. pre nás texely) majú prístup len k hodnotám svojich susedov, kdežto v prípade PRAM má každý procesor(počítaný texel) prístup k aktuálnej hodnote všetkých texelov v textúre. Dôvod pre využitie celulárnych automatov je okrem iného aj ten, že môj školiteľ ako svoju diplomovku písal interpreter jazyka Texture Language na tvorbu textúr na celulárnom automate :)
 Na to, aby som bola schopná napísať algoritmus pre paralelný stroj, som dostala za úlohu naprogramovať si v Texture Language niektoré z metód. Podarilo sa mi zatiaľ naprogramovať Voronoiove diagramy a Midpoint-Displacement algoritmus - i keď v druhom prípade je plne funkčné len šírenie informácie o najbližšom vyrátanom bode (ak má bod rovnako ďaleko k 2 vyrátaným bodom, zinterpoluje hodnoty tých dvoch bodov a pridá náhodnú odchýlku). Akonáhle zapojím do výpočtu aj náhodnú odchýlku, výsledná textúra sa prestane podobať na MPD algoritmus, jednak kvôli obtiažnemu zisťovaniu poradového čísla iterácie (aby sa rozpätie pre odchýlku postupne zmenšovalo), jednak absencii logických spojok pri if-then-else výraze, preto programátor musí ručne ošetriť všetky možnosti a mne zjavne niektorý špeciálny prípad ušiel :) Principiálne je ale algoritmus správny a pre teoretický model postačí.

Voronoiov diagram v Texture Language spolu s pomocnými premennými v jednotlivých bunkách
zľava 1.súradnice klastrov 2. x-ová súradnica najbližšieho stredu 3. y-ová súradnica najbližšieho stredu 4. samotný diagram 5. diagram v tvare 1-d 


MPD algoritmus v TLA vo vývoji
zľava 1.výsledok 2. informácia o vzdialenosti k najbližšiemu vyrátanému bodu vo vodorovnom smere 3. informácia o najbližšom vyrátanom bode vo zvislom smere 4. výška najbližšieho vodorovného vyrátaného bodu 5. viď 4. ale vo zvislom smere
Nakoniec ešte ponúkam GLSL aplikáciu na stiahnutie v stave k dnešnému dňu (4.5.2011). Prosím, berte na vedomie, že je to "work-in-progress" a do finálnej podoby má ešte stále ďaleko.



Žiadne komentáre:

Zverejnenie komentára