KÉPFELDOLGOZÁS A DIRECTX 9 MAGAS SZINTŰ ÁRNYALÓ NYELVÉNEK SEGÍTSÉGÉVEL



Hasonló dokumentumok
Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Előfeldolgozó rendszer Tömbök. Dr. Bécsi Tamás 4. Előadás

Java II. I A Java programozási nyelv alapelemei

HLSL programozás. Grafikus játékok fejlesztése Szécsi László t06-hlsl

Programozás I. 3. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

Grafikus csővezeték és az OpenGL függvénykönyvtár

Textúrák. Szécsi László

Szoftvertechnológia alapjai Java előadások

Grafikus csővezeték 1 / 44

Számítógépes grafika

Java programozási nyelv

Programozás BMEKOKAA146. Dr. Bécsi Tamás 1. Előadás

OOP #14 (referencia-elv)

Pénzügyi algoritmusok

Java II. I A Java programozási nyelv alapelemei

Informatika terméktervezőknek

Számítástechnika I. BMEKOKAA152 BMEKOKAA119 Infokommunikáció I. BMEKOKAA606. Dr. Bécsi Tamás

C# nyelv alapjai. Krizsán Zoltán 1. Objektumorientált programozás C# alapokon tananyag. Általános Informatikai Tanszék Miskolci Egyetem

2D képszintézis. Szirmay-Kalos László

HLSL programozás. Szécsi László

Bevezetés, a C++ osztályok. Pere László

Mintavételes szabályozás mikrovezérlő segítségével

és az instanceof operátor

GPU Lab. 4. fejezet. Fordítók felépítése. Grafikus Processzorok Tudományos Célú Programozása. Berényi Dániel Nagy-Egri Máté Ferenc

1. Bevezetés 1. Köszönetnyilvánítás A számítógépes játékfejlesztésről 3

1. Egyszerű (primitív) típusok. 2. Referencia típusok

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

1.1. A forrásprogramok felépítése Nevek és kulcsszavak Alapvető típusok. C programozás 3

1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben?

Bevezetés a programozásba. 9. Előadás: Rekordok

Programozás II. 2. Dr. Iványi Péter

Mechatronika és mikroszámítógépek 2017/2018 I. félév. Bevezetés a C nyelvbe

Plakátok, részecskerendszerek. Szécsi László

Készítette: Nagy Tibor István

Java grafikai lehetőségek

Függvények. Programozás alapjai C nyelv 7. gyakorlat. LNKO függvény. Függvények(2) LNKO függvény (2) LNKO függvény (3)

Programozás alapjai C nyelv 7. gyakorlat. Függvények. Függvények(2)

Függvények. Programozás I. Hatwágner F. Miklós november 16. Széchenyi István Egyetem, Gy r

1. Jelölje meg az összes igaz állítást a következők közül!

Transzformációk. Grafikus játékok fejlesztése Szécsi László t05-transform

Bevezetés a programozásba Előadás: A const

Programozás I gyakorlat

C++ programozási nyelv Konstruktorok-destruktorok

OpenGL Compute Shader-ek. Valasek Gábor

Tanács Attila. Képfeldolgozás és Számítógépes Grafika Tanszék Szegedi Tudományegyetem

A C programozási nyelv I. Bevezetés

A C programozási nyelv I. Bevezetés

Direct3D pipeline. Grafikus játékok fejlesztése Szécsi László t03-pipeline

Bevezetés a programozásba II. 5. Előadás: Másoló konstruktor, túlterhelés, operátorok

Programozás BMEKOKAA146. Dr. Bécsi Tamás 2. előadás

C programozási nyelv Pointerek, tömbök, pointer aritmetika

Számítógépes Graka - 4. Gyak

OOP: Java 8.Gy: Abstract osztályok, interfészek

Java programozási nyelv 5. rész Osztályok III.

Információ megjelenítés Számítógépes ábrázolás. Dr. Iványi Péter

Programozás II. 4. Dr. Iványi Péter

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós március 3. Széchenyi István Egyetem, Gy r

Programozási nyelvek I. 5. előadás (Gregorics Tibor anyagának felhasználásával)

1. Bevezetés A C++ nem objektumorientált újdonságai 3

Occam 1. Készítette: Szabó Éva

Programozas 1. Strukturak, mutatok

1. Alapok. Programozás II

Alprogramok, paraméterátadás

Információ megjelenítés Számítógépes ábrázolás. Dr. Iványi Péter

A C# programozási nyelv alapjai

Programozás alapjai C nyelv 4. gyakorlat. Mit tudunk már? Feltételes operátor (?:) Típus fogalma char, int, float, double

Fejlett programozási nyelvek C++ Iterátorok

Adatok ábrázolása, adattípusok

3D-s technológiák a játékfejlesztésben UDK bevezetés

Programozás 1. Dr. Iványi Péter

Nagy HF u tmutato 2011/2012 II. fe le v

Valasek Gábor

Párhuzamos és Grid rendszerek

Grafikus csővezeték 2 / 77

Programozási alapismeretek beadandó feladat: ProgAlap beadandó feladatok téma 99. feladat 1

Programozás C++ -ban

Raszteres elemzés végrehajtása QGIS GRASS moduljával 1.7 dr. Siki Zoltán

Mit tudunk már? Programozás alapjai C nyelv 4. gyakorlat. Legnagyobb elem keresése. Feltételes operátor (?:) Legnagyobb elem keresése (3)

A C# PROGRAMOZÁSI NYELV

Programozás C és C++ -ban

Felhasználó által definiált adattípus

GPU Lab. 14. fejezet. OpenCL textúra használat. Grafikus Processzorok Tudományos Célú Programozása. Berényi Dániel Nagy-Egri Máté Ferenc

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós április 4. Széchenyi István Egyetem, Gy r

Árnyalás, env mapping. Szécsi László 3D Grafikus Rendszerek 3. labor

Programozási nyelvek JAVA EA+GY 1. gyakolat

C++ referencia. Izsó Tamás február 17. A C++ nyelvben nagyon sok félreértés van a referenciával kapcsolatban. A Legyakoribb hibák:

A MATLAB alapjai. Kezdő lépések. Változók. Aktuális mappa Parancs ablak. Előzmények. Részei. Atomerőművek üzemtana

Java programozási nyelv 6. rész Java a gyakorlatban

Járműfedélzeti rendszerek II. 1. előadás Dr. Bécsi Tamás

Programozás I gyakorlat

Interfészek. PPT 2007/2008 tavasz.

Bevezetés a CGI-be. 1. Történelem

Tömbök kezelése. Példa: Vonalkód ellenőrzőjegyének kiszámítása

A C programozási nyelv IV. Deklaráció és definíció

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*;

STL gyakorlat C++ Izsó Tamás május 9. Izsó Tamás STL gyakorlat/ 1

Vizuális, eseményvezérelt programozás XI.

Járműfedélzeti rendszerek II. 4. előadás Dr. Bécsi Tamás

Programozási környezetek

Átírás:

Budapesti Műszaki Főiskola Neumann János Informatikai Főiskolai Kar Szoftvertechnológia Intézet TUDOMÁNYOS DIÁKKÖRI DOLGOZAT KÉPFELDOLGOZÁS A DIRECTX 9 MAGAS SZINTŰ ÁRNYALÓ NYELVÉNEK SEGÍTSÉGÉVEL Szerzők: Szőke Imre műszaki informatika szak, III. évfolyam Konzulens: Vámossy Zoltán főiskolai docens Budapest, 2005

Tartalomjegyzék 1 BEVEZETÉS... 4 2 DIRECTX ARCHITEKTÚRÁJA... 5 2.1 RENDSZER INTEGRÁCIÓ... 5 2.2 GRAFIKUS FUTÓSZALAG... 6 3 HLSL NYELV ISMERTETÉSE... 8 3.1 KULCSSZAVAK... 8 3.2 ADATOK... 8 3.2.1 Skalár adattípusok... 9 3.2.2 Vektor adattípusok... 9 3.2.3 Mátrix adattípusok... 9 3.2.4 Textúrák... 10 3.2.5 Mintavételezők... 10 3.2.6 Struktúrák... 11 3.2.7 Típusmódosítók... 11 3.2.8 Típus konverziók... 12 3.3 MŰVELETEK... 13 3.3.1 Saját függvények... 13 3.3.2 Matematikai függvények... 14 3.3.3 Textúra mintavételező függvények... 14 3.4 ÁRNYALÓ PROGRAM BEMENETEI... 15 3.4.1 Változatlan bemenő adatok... 15 3.4.2 Változó bemenő adatok... 15 3.5 ÁRNYALÓ PROGRAM KIMENETEI... 17 3.6 SAJÁT PROGRAMBA VALÓ ÁGYAZÁS... 18 4 KÉPFELDOLGOZÁS... 20 4.1 KÉPTÉRBEN TÖRTÉNŐ MŰVELETEK... 20 4.1.1 Pont alapú transzformációk... 20 4.1.2 Ablak vagy maszk alapú transzformációk... 23 4.1.3 Teljes képre vonatkozó transzformációk... 25 4.1.4 Geometriai transzformációk... 25 4.2 FREKVENCIA TARTOMÁNYBAN TÖRTÉNŐ MŰVELETEK... 25 5 ÉRTÉKELÉS... 26 6 MAGASSZINTŰ ÁRNYALÓ NYELVEK JÖVŐJE... 26 7 ELÉRHETŐSÉG... 26 8 IRODALOMHIVATKOZÁSOK... 27 9 ÁBRAJEGYZÉK... 27 2

Tartalmi kivonat A dolgozat rövid áttekintést ad a Direct3D architektúrájáról rámutatva, hogy miként és miért használható hatékonyan a grafikus processzor bizonyos képfeldolgozási feladatok megoldására. A tematikában kiemelt szerepet kap az elméleti alapok lefektetése után a magas szintű árnyaló nyelv szintaktikájának és szemantikájának bemutatása, kitérve a saját programba való beágyazására is. Végül bemutatásra kerül pár alapvető képfeldolgozó algoritmus elméleti összefoglalása, amit az implementálásuk követ. 3

1 Bevezetés Gondolkodtunk már azon, hogy mi hajtja végre a programjaink utasításait? Valószínűleg nem. Ugyanis a válasz olyan egyszerű, hogy gondolkodásra sem érdemes. Vagy mégis? Nincs még egy olyan számítógépes alkatrész, amely dinamikusabban fejlődne, mint a videokártya. Valóban csak a játékmániásoknak érdemes lecserélni a videokártyát félévenként? Ha már kiadjuk a pénzt egy komolyabb videokártyára, talán elvárható lenne, hogy ne csak a játékprogramok használják ki a grafikus hardver nyújtotta lehetőségeket. Véleményem szerint ideje a fejlesztőknek elgondolkodni, azon hogy ne csak a CPU-t terheljék kódjaikkal, hanem a GPU-t is. Mire alapozom ezen kijelentést? Vegyünk egy élvonalba tartozó CPU-t és egy GPU-t és hasonlítsuk össze mindössze a tranzisztorok számát. Pentium XE 840 230 milliót, a Radeon X1800 pedig 321 millót tartalmaz. Továbbá elmondható a Radeon X1800-ról, hogy 16 pixel és 8 csúcspont árnyaló processzort foglal magába többszálas technikát is használva. Természetesen nem lehet teljes mértékben összevetni egy általános célú processzort egy grafikai feladatok megoldására kihegyezett cél processzorral, de meg kell állapítanunk gyakran kihasználatlan erőforrás lapul gépünkben. 2002-ben megjelentek az első magas szintű árnyaló nyelvek, melyek segítségével már kényelmes programozási keretek között cserélhetjük le a "beégetett" funkciókat a saját ötleteinkkel. A téma fontosságát bizonyítja, hogy mindegyik vezető grafikus alrendszer készítő és videokártya gyártó kifejlesztette a saját nyelvét. Az ATI ASHLI, az nvidia Cg, a DirectX HLSL az OpenGL pedig GLSL néven illeti saját megvalósításait. Jelen dolgozat a DirectX HLSL nyelvét mutatja be, mely segítségével a grafikus kártyát programozva valósíthatjuk meg elképzeléseinket. A nyelv általános ismertetése után következő példák ugyan csak képfeldolgozás témaköréből kerülnek ki, de számos más feladat is hatékonyan oldható meg videokártya segítségével. 4

2 DirectX architektúrája 2.1 Rendszer integráció [6][7] alapján A grafikában alkalmazott eljárások, módszerek tárgyalásához tisztában kell lennünk azzal a számítógépes környezettel, amelyben a grafikus alkalmazásaink futnak. A számítógépes környezet szoftver és hardver komponensekből áll. [A1]. Ábra Direct3D rendszer integráció Az [A1]. ábra a Windows operációs rendszeren futó grafikus alkalmazás környezetét mutatja be. A grafikus programok futtatásához szükség van célhardverre. A grafikus hardvert az operációs rendszer a hozzá kapcsolódó illesztőprogramok interfészein (DDI) keresztül kezeli. A hardvereket az operációs rendszerek biztonságos és ellenőrzött interfészek mögé "rejtik" el. Számunkra ez azt jelenti, hogy a grafikus alkalmazások közvetlenül nem kezelhetik a grafikus hardvereket, csak az operációs rendszer által biztosított interfészeken, illetve az ezekre épülő könyvtárakon keresztül érhetik el azokat. A Windows GDI (Graphics Device Interface) egy olyan absztrakciós szintet definiáló rendszerkomponens, amelynek a segítségével az alkalmazások a képernyőre tudnak rajzolni. A GDI-t sajnos nem grafikus és multimédia célokra, hanem üzleti alkalmazásokhoz (szövegszerkesztő, táblázatkezelő) fejlesztették ki. A GDI filozófia szerint a keletkező kép a rendszermemóriába, és nem a videokártyába kerül, továbbá a GDI felület nincs felkészítve bővítésre, a videokártyák által támogatott új funkciók befogadására. Játékokhoz és multimédiás alkalmazásokhoz (videózás) a lassúsága miatt sem alkalmas. A megoldást a DirectX API grafikai részét tartalmazó Direct3D jelenti, amely eszközfüggetlen interfészt biztosít az alkalmazás számára a grafikus processzor eléréséhez. A Direct3D egy létrehozott eszközön (device) keresztül fér hozzá a hardverhez. A Direct3D eszköz egy megjelenítési alkotóelem, amely magában foglalja a rajzolási állapotot is. Mindemellett egy Direct3D eszköz tartalmazza a transzformációs és megvilágítási műveleteket és a képernyő ponttá való átalakítást (raszterizálás) is. Az előzőeket az [A2]. ábra szemlélteti. 5

[A2]. Ábra. Direct3D eszköz architektúra Jelenleg a Direct3D két fő eszköz típust támogat: a HAL eszközt és a referencia eszközt. HAL (Hardware Abstraction Layer) eszköz: Az elsődleges eszköztípus a HAL eszköz, amely támogatja a hardveresen gyorsított raszterizálást és mind a hardveres, mind pedig a szoftveres csúcspont feldolgozást. A hardver absztrakciós réteget (HAL) a videokártya gyártók csatolóprogramban (driver) valósítanak meg. A kompatibilitás érdekében minden kártyagyártó kötelezően ugyanazt a HAL felületet mutatja. A HAL-nak része egy olyan metódus, amellyel lekérdezhető, hogy melyek a kártya által hardveresen gyorsított rajzolási funkciók. Ha egy funkció hiányzik, akkor azt a DirectX HEL emulációs rétege (Hardware Emulation Layer) fogja elvégezni. Természetesen ez lelassítja a programot, de a sebességcsökkenéstől eltekintve az alkalmazás ebből semmit sem vesz észre. Referencia eszköz: A referencia eszköz támogat minden Direct3D jellemzőt. A minden funkció megvalósítását szoftveresen végzi a CPU segítségével, így az eredmény nem túl gyors, de minden gépen lefut. A referencia eszközt csak funkciók tesztelésére, demonstrálására használják. 2.2 Grafikus futószalag [6] alapján A grafikus futószalag a hardver adottságokat kihasználva biztosítja a hatékony színtér feldolgozást és megjelenítését. Az [A3]. ábra szemlélteti a futószalag építőelemeit. [A3]. ábra Direct3D grafikus futószalag 6

Futószalag komponens Csúcspont adatok (Vertex Data) Primitív adatok (Primitive Data) Tesszeláció (Tesselation) Csúcspont feldolgozás (Vertex processing) Geometriai feldolgozás (Geometry processing) Textúra felület (Textured surface) Textúra mintavételezés (Texture sampler) Pixel feldolgozás (Pixel processing) Pixel megjelenítése (Pixel rendering) Leírás A modell transzformálatlan csúcspontjai, ami a memóriában egy csúcspont pufferben kerül tárolásra A geometriai primitívekről szóló adatokat a csúcspont adatokhoz kapcsolják index puffer segítségével. Ez meghatározza, miként dolgozzuk fel a csúcspont adatokat. Primitív típusa lehet pont, vonal, háromszög és poligon. A tesszelációs egység a magas szintű primitíveket, hálókat, elemi szintűekre bontja, és csúcspont pufferben eltárolja Direct3D transzformációkat hajtanak végre a tárolt csúcspontokon. (Pl. a modell koordináta rendszerből áttérés a képtér koordinátarendszerébe) Kamera modellnek megfelelő képsík vágás, takarási feladatok megoldása, transzformált csúcspontok raszterizálása (képernyő pixelekre való bontás) Felületek textúra koordinátáinak megadása Az input textúrán szűrést hajtunk végre a részletezettség szintjének megfelelően. Pixel árnyaló műveleteket használunk a bejövő csúcspont és textúra adatokon, hogy a kimenő szín értékeket meghatározzuk. A végső megjelenítési fázis módosítja a pixel színét az alfa csatornának, áttetszőségnek és mélységnek megfelelően. A grafikus processzorok lehetőséget biztosítanak arra, hogy ezen működési modellbe két pontos is "belenyúljunk". A geometriai motor működését, azaz a csúcspontok és kapcsolódó adataik transzformálását a csúcspont-árnyalók segítségével módosíthatjuk, míg az árnyaló egység előre beprogramozott algoritmusait a pixel-árnyalókkal cserélhetjük le. 7

3 HLSL nyelv ismertetése [1] alapján 3.1 Kulcsszavak A kulcsszavak előre definiált azonosítók, amelyeket a HLSL nyelv fenntart, így ezeket nem használhatjuk a programunkban azonosítóként. A '*' jelölt kulcsszavak érzékenyek a kis- és nagybetűkre. asm * bool compile const decl* do double else extern false float for half if in inline inout int matrix * out pass * pixelshader * return sampler shared static string * struct technique * texture * true typedef uniform vector * vertexshader * void volatile while A következő kulcsszavak jelenleg nem használtak, de fent vannak tartva jövőbeni felhasználás céljából: auto break compile const char class case catch default delete const_cast continue explicit friend dynamic_cast enum mutable namespace goto long private protected new operator reinterpret_cast short public register static_cast switch signed sizeof throw try template this typename unsigned using union virtual 3.2 Adatok A HLSL az adattípusok széles választékát kínálja. A skalár és struktúra típusú adatok a hagyományos magas szintű programozási nyelvekben megszokottak. Az újdonságok a vektorok és mátrixok adattípusok nyelvi szintű támogatásában rejlik. Továbbá a nyelv sajátosságainak megfelelően új adattípusok (textúra, mintavételező) is szerepelnek. 8

3.2.1 Skalár adattípusok A nyelv a következő skalár adattípusokat támogatja: Adattípus bool int half float double Ábrázolható értékek igaz vagy hamis 32 bites előjeles egész szám 16 bites lebegőpontos szám 32 bites lebegőpontos szám 64 bites lebegőpontos szám 3.2.2 Vektor adattípusok Az egyik leggyakrabban használt adattípus a HLSL nyelvben a vektor adattípus. Vektorok deklarálásának számos módja van, beleértve a következőket is: vector vector <type, size> Egy négydimenziós vektor, melynek minden eleme float típusú A vektor dimenziója size és az egyes elemek adattípusa valamilyen skalár típus (type) A szokásos C stílusú vektor deklaráción kívül, leggyakrabban a típust és azt közvetlenül követő 2, 3 vagy 4 szám megadásával teszik. A következő példában egy 4 elemű float típusú vektorokat deklarálunk különböző módon: float4 fvector0; float fvector1[4]; vector fvector2; vector <float, 4> fvector3; A vektor definiálása után a komponensekhez hozzáférhetünk a szokásos tömbindexeléssel, valamint az x,y,z,w vagy a r,g,b,a névtereken keresztül. Egyszerre több elemhez is hozzáférhetünk, de ügyeljünk arra, hogy ne keverjük a névtereket. float4 pos = 3.0f, 5.0f, 2.0f, 1.0f; float value0 = pos[0]; // value0 értéke 3.0f float value1 = pos.x; // value1 értéke 3.0f float value2 = pos.g; // value2 értéke 5.0f float2 vec0 = pos.xy; // vec0 értéke 3.0f, 5.0f float2 vec1 = pos.ry; // Érvénytelen a névterek keverése miatt 3.2.3 Mátrix adattípusok Egy másik gyakran használt változó típus a mátrix, amely egy kétdimenziós adattömb. A vektorokhoz hasonlóan a mátrixok is elemi adattípusokból épülnek fel: bool, int, half, float, double. A mátrixok mérete bármekkora lehet, de általában 4 sorból és oszlopból állok a leggyakoriabbak. A vektorokhoz hasonlóan deklarálhatjuk őket: 9

float3x4 mat0; matrix<float, 3, 4> mat1; float4x4 mat2; Az egyes elemek eléréséhez, használhatjuk a szokásos tömbindexelési technikát. Például a mat2 mátrix bal felső eleme: float fvalue = mat2[0][0]; Használhatunk beszédes neveket is. A nulla alapú sor oszlop elérés a következő: _m00, _m01, _m02, _m03 _m10, _m11, _m12, _m13 _m20, _m21, _m22, _m23 _m30, _m31, _m32, _m33 Az egy alapú sor oszlop elérés a következő: _11, _12, _13, _14 _21, _22, _23, _24 _31, _32, _33, _34 _41, _42, _43, _44 Mátrix deklarálást, elem és vektor szintű hozzáférést a következő példa szemlélteti: float2x2 fmat = 3.0f, 5.0f, // row 1 2.0f, 1.0f; // row 2 float value0 = fmat[0]; // value0 is 3.0f float value1 = fmat._m00; // value1 is 3.0f float value2 = fmat._12 // value2 is 5.0f float value3 = fmat[1][1] // value3 is 1.0f float2 vec0 = fmat._21_22; // vec0 is 2.0f, 1.0f float2 vec1 = fmat[1]; // vec1 is 2.0f, 1.0f 3.2.4 Textúrák Egy textúrat a texture kulcsszóval vezethetünk be. Léteznek még texture1d, texture2d, texture3d és texturecube kulcsszavak is amelyek a textúra típusát pontosíthatják, de alapvetően a mintavételezési állapot és textúra színt kikereső függvények határozzák meg az eredményt. A textúra kép fájlból való betöltését vagy generálását és átadását a főprogram végzi el. Példa egy textúra deklarálására: texture g_meshtexture; 3.2.5 Mintavételezők Minden egyes textúrához deklarálni kell egy mintavételezőt a sampler kulcsszóval. Lehetőség van egy textúrához több mintavételezőt definiálni különböző paraméterekkel. Ezt a technikát gyakran használják a képfeldolgozás során. A textúra térkép típusától függően a felhasználható kulcsszavak: 10

sampler1d 1 dimmenziós textúra mintavételezésére sampler2d 2 dimmenziós textúra mintavételezésére sampler3d 3 dimmenziós textúra mintavételezésére samplercube Kiterített kocka alapú textúra mintavételezésére Egy mintavételező deklarálása a sampler kulcsszóval kezdődik, amit a mintavételező neve követ. Egyenlőségjelet követően a mintavételezési állapotot vezetjük be a sampler_state kulcsszóval, ami meghatározza a textúra szűrés típusát és a textúra címzés módját. A következő példában egy g_ MeshTexture nevű textúra mipmap, kicsinyítési, nagyítási szűrőjét lineáris interpolációra állítottuk be. sampler MeshTextureSampler = sampler_state Texture = <g_meshtexture>; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; ; Mintavételezési állapotról további részletes információkat a DirectX SDK-ban találhatunk. 3.2.6 Struktúrák HLSL nyelv is biztosítja a lehetőséget a saját adatszerkezetek létrehozására. Struktúrák használata növeli az áttekinthetőséget, kényelmes teszi az adatok kezelését. Struktúra deklarálását a struct kulcsszóval kezdjük, amit a struktúra neve követ. Kapcsos zárójelek között pedig felsorolásra kerül az elemi és összetett adattípusok. Egy példa a struktúrák definiálására: struct VS_OUTPUT float4 Pos : POSITION; float3 View : TEXCOORD0; float3 Normal:TEXCOORD1; float3 Light1: TEXCOORD2; float3 Light2: TEXCOORD3; float3 Light3: TEXCOORD4; ; 3.2.7 Típusmódosítók Van néhány típusmódosító, amelyre szükségünk lehet a HLSL árnyaló programunkban. A const kulcsszó lehetővé teszi, hogy a változó értékét ne lehessen megváltoztatni az árnyaló programunkban, azaz definiálás során megadott állandó értékkel szerepel a program futása során. Amennyiben a változót az értékadás bal oldalára tennénk, fordítási hibát kapnánk. 11

A row_major és a col_major típus módosítók a mátrix elvárt tárolási szerkezetét határozzák meg a hardverben. A row_major azt jelöli, hogy a mátrix minden egyes sora egy konstans regiszterbe lesz tárolva, míg a col_major esetén a mátrix egyes oszlopai lesznek egy regiszterben tárolva. Az oszlop folytonos az alapértelmezés. Tárolási osztálymódosítók A tárolási osztály módosító a megadott változó érvényességi körét és élettartamát közli a fordító felé. Ezek a módosítók opcionálisak és bármilyen sorrendben a változó típusa elé írhatók. Egy változó lehet static vagy extern (a két módosító egymást kizárja). Globális hatáskörrel a static módosító azt jelenti, hogy a változót csak az árnyaló program érheti el az alkalmazás az API-n keresztül nem. Minden nem statikus globális változót a főprogram az API-n keresztül módosítani tud. Lokális hatáskörű statikus változót, akkor használunk, ha a függvényhívások között is meg kívánjuk tartani a változó értékét. Az extern módosítót globális változóknál használhatjuk, hogy módosítható legyen kívülről is. Ez redundáns ugyanis ez az alapértelmezett viselkedése egy globális változónak. A shared módosítót használatos, hogy megadjunk egy megosztott globális változót, amit így a többi árnyaló programunk is elér. A uniform típusú változó értékét a HLSL árnyaló programon kívülről is be lehet állítani (a Set*ShaderConstant*() API függvényen keresztül). A globális változókat automatikusan uniform típusként kezelik. Például a következő globális változókat deklaráljuk: extern float translucencycoeff; const float gloss_bias; static float gloss_scale; float diffuse; A diffuse és a translucencycoeff változók értéke beállítható a Set*ShaderConstant*() API-n keresztül és az árnyaló program képes ezek értékét megváltoztatni. A konstans gloss_bias változó szintén beállítható Set*ShaderConstant*() segítségével, de nem módosíthatja az értékét az arnyaló program. Végül a gloss_scale statikus változót nem lehet beállítani a Set*ShaderConstant*() függvénnyel, de az árnyaló képes ennek értékét módosítani. 3.2.8 Típus konverziók Hasznos, ha jártasak vagyunk a típuskonverziókkal, ugyanis így elkerülhetünk csapdákat és hatékony kódot írhatunk. Alacsonyabb vagy magasabb elemszámra hozás esetén gyakran használják a konverziót. Például a következő esetben a konstans 0.0f float számot float40.0f, 0.0f, 0.0f, 0.0f alakúra kényszerítjük, hogy inicializáljuk a vresult változót. float4 vresult = 0.0f; Hasonló módon magasabb dimenziószámú adattípust (mint a mátrix vagy vektor) alacsonyabb dimenziószámra konvertálhatunk. Ebben az esetben az extra adatokat kihagyjuk. Erre példa a következő pár sor: 12

float3 vlight; float ffinal, fcolor; ffinal = vlight * fcolor; Ebben az esetben a vlight vektort float típusra hoztuk, úgy hogy a vektornak csak az első elemét szoroztuk be az fcolor float számmal. Az utolsó sorral ekvivalens kifejezés a következő: ffinal = vlight.x * fcolor; További típuskasztolási szabályokat lásd [1] 12-13 oldala. 3.3 Műveletek Az adatokat operátorok és függvények segítségével dolgozhatjuk fel. Az operátorok a megszokott módon működnek a következőktől eltekintve. A HLSL esetén nyelvi szintre emelték a vektorok és mátrixok kezelését, azaz a megszokott operátorok (+,-,*,/) értelmezve van az adattípusokon, de fontos megjegyezni, hogy ezek elemenkénti végrehajtást jelentenek. Lássunk egy példát: float4 vtone = vbrightness * vexposure; Feltételezve hogy vbrightness és vexposure float4 típusú, a következő kifejezéssel ekvivalens float4 vtone; vtone.x = vbrightness.x * vexposure.x; vtone.y = vbrightness.y * vexposure.y; vtone.z = vbrightness.z * vexposure.z; vtone.w = vbrightness.w * vexposure.w; Tehát a * operátor nem a két vektor keresztszorzata. A mátrixok szorzatára is érvényes az a megállapítás, hogy ez a típusú szorzás nem a matematikában megszokott szorzás. A mátrix szorzatot és a kereszt szorzatot a mul() belső függvény segítségével érhetjük el. A mul() függvényen kívül a HLSL nyelv számos belső függvényt tartalmaz, melyek megkönnyítik a programozók dolgát. Nagyrészük matematikai függvény, ami a kényelmet szolgálja, míg a többi függvény a textúra adatok kinyerésére szolgálnak. 3.3.1 Saját függvények A HLSL esetén is írhatunk tetszőleges számú függvényt. Mindössze az utasítások számát illik szemügyre venni, hogy a kiválasztott fordítási célhardver maximális utasításhosszát ne lépjük túl. Példa egy saját függvényre: float4 myfunction(float4 a, float4 b, float4 c ) return (a * b + c); 13

3.3.2 Matematikai függvények A HLSL fordító a matematikai függvényeket mikro utasításokká alakítja. Néhány esetben, mint például az abs() és a dot(), ezek közvetlenül egy assembly szintű utasításra képeződnek le, míg a többi assembly utasítások sorozatára (pl: refract()). Néhány esetben, mint például a ddx(), ddy() és fwidth(), pedig nem lehet minden hardverre lefordítani. Beépített matematikai utasítások listája: abs(x) acos(x) all(x) any(x) asin(x) atan(x) atan2(y, x) ceil(x) clip(x) cos(x) cosh(x) cross(a, b) D3DCOLORtoUBYTE4(x) ddx(x) ddy(x) degrees(x) distance(a, b) dot(a, b) exp(x) exp2(a) faceforward(n, i, ng) floor(x) fmod(a, b) frac(x) frexp(x, out exp) fwidth(x) isfinite(x) isinf(x) isnan(x) ldexp(x, exp) len(v) length(v) lerp(a, b, s) log(x) log10(x) log2(x) max(a, b) min(a, b) modf(x, out ip) mul(a, b) pow(x, y) radians(x) reflect(i, n) refract(i, n, eta) round(x) rsqrt(x) saturate(x) sign(x) sin(x) sinh(x) sqrt(x) step(a, x) sincos(x, out s, out c) tan(x) tanh(x) transpose(m) smoothstep(min, max, x) Az utasítások nevei elég beszédesek, de pontos leírást találunk a DirectX SDK-ban. 3.3.3 Textúra mintavételező függvények Tizenhat textúra mintavételező utasítás szolgál az adatok kinyerésére a textúrából. Négy textúra típus van (1D, 2D, 3D, Cube) és mindegyikhez négyfajta betöltési mód (hagyományos, hagyományos deriválttal, projektív és eltolt súlypontú). Így áll elő a tizenhat kombináció: tex1d(s,t) tex1d(s, t, ddx, ddy) tex1dproj(s, t) tex1dbias(s, t) tex2d(s,t) tex2d(s, t, ddx, ddy) tex2dproj(s, t) tex2dbias(s, t) tex3d(s,t) tex3d(s, t, ddx, ddy) tex3dproj(s, t) tex3dbias(s, t) texcube(s,t) texcube(s, t, ddx, ddy) texcubeproj(s, t) texcubebias(s, t) Értelmezés: s egy előzőleg deklarált mintavételező t a textúra dimmenziójának és a betöltés típusának megfelelő vektor ddx és ddy az x, y irányú derivált vektorok. 14

3.4 Árnyaló program bemenetei Csúcspont és pixel árnyalóba érkező adatok lehetnek változók (varying) és változatlanok (uniform). Csúcspont árnyaló esetén a változó adatok (mint pl. a pozíció, normál vektor, stb.) a csúcspont pufferből érkeznek. A változatlan adatok (mint pl. anyag színe, világ transzformáció) pedig állandóak az egyes csúcspontokra nézve, így konstans táblából származnak. 3.4.1 Változatlan bemenő adatok A HLSL nyelvben kétféle módon is definiálhatunk változatlan adatokat. A leggyakrabban használt metódus erre, hogy globálisnak deklarálunk egy változót. Egy árnyaló függvény paraméterlistájában a változó elé írt uniform a másik lehetőség. Mindkét esetet illusztrálja a következő kódrészlet: float4 UniformGlobal; float4 main( uniform float4 UniformParam ) : POSITION return UniformGlobal * UniformParam; Az árnyaló programban használt uniform változókat az alkalmazás egy konstans táblán keresztül ér el. A konstans tábla tartalmazza a típus információkat és az alapértelmezés szerinti értéket. A konstans tábla változói külön regiszterbe kerülnek, konstans regiszterekbe. Ezt a táblát fel kell tölteni az árnyaló program végrehajtása előtt. 3.4.2 Változó bemenő adatok Bemeneti sémákkal lehet specifikálni a változó bemenő adatokat. Minden árnyaló bemenetet sémával kell ellátni, vagy uniform kulcsszóval konstansként kell megadni. Ha egy bemenő adatot nem jelölünk meg sémával vagy a uniform kulcsszóval, akkor az árnyalót nem lehet lefordítani. Sémákat azért használunk, hogy a grafikus futószalag előző lépésének kimenetét a következőhöz kapcsoljuk. Például a POSITION0 séma arra használható, hogy a csúcspont puffer pozíció adatait a csúcspont árnyalóhoz kössük A csúcspont és pixel árnyalóknak különböző bemenő sémáik vannak, mivel a feldolgozás különböző fázisait végzik el. A csúcspont árnyaló bemenő sémái csúcsonkénti információkat tartalmaznak, amelyek a csúcspont pufferből kerülnek az árnyaló programba (mint például pozíció, normál vektor, textúra koordináta, szín, stb.). A pixel árnyaló bemeneti sémái pixelenkénti információkat tartalmaznak a raszterizáló egység számára. A csúcspont árnyaló által szolgáltatott kimenetet dolgozza fel a pixel árnyaló. 15

A bemenő adatokhoz kétféle képen is hozzárendelhetjük a sémákat. Az egyik mód a változó után írt ':' és a séma neve. A másik mód egy bemeneti struktúra definiálása, ahol minden egyes elemhez hozzárendeljük a sémát. A következő példa mindkettőt bemutatja: // Bemeneti struktúra definiálása sémával struct InStruct float4 Pos1 : POSITION1 ; // Pozíció adatként deklarált Pos nevű változó float4 main( float4 Pos : POSITION0, InStruct In ) : POSITION return Pos * In.Pos1; // Színként deklarált Col nevű változó float4 mainps( float4 Col : COLOR0 ) : COLOR return Col; Csúcspont árnyaló bemeneti sémái: Séma Leírás POSITIONn Pozíció BLENDWEIGHTn Vegyítési súly BLENDINDICESn Vegyítési index NORMA n Normálvektor PSIZEn Pont mérete COLORn Szín TEXCOORDn Textúra koordináták TANGENTn Tangens BINORMALn Kétirányú normális TESSFACTORn Tesselációs faktor Pixel árnyaló bemeneti sémái: Séma Leírás COLORn Szín TEXCOORDn Textúra koordináták Ahol n egy egész szám. Például: POSITION0, COLOR1, stb. 16

3.5 Árnyaló program kimenetei A csúcspont és pixel árnyalók kimenő adatokat biztosítanak az őket követő grafikus futószalag egységeknek. A kimeneti sémák specifikálják, hogy a generált kimenő adatokat milyen módon kapcsolódnak a következő futószalag-fokozat bemenetéhez. Csúcspont árnyaló kimeneti sémái a pixel árnyalóhoz és raszterizálási fázishoz kötik a kimenő adatokat. Minden csúcspont árnyaló kimenetének tartalmazni kell legalább a pozíció adatokat, amit a raszterizáló egység fog felhasználni és nem a pixel árnyaló. Séma Leírás POSITION Pozíció PSIZE Pont mérete FOG Köd COLORn Szín (pl. COLOR0) TEXCOORDn Textúra koordináták (pl. TEXCOORD0) Pixel árnyaló kimenetének minimálisan egy szín sémát kell tartalmaznia, amit az alfa csatorna alapján történő színvegyítési fokozathoz kapcsol. A mélység kimeneti sémát a cél mélység értékének megváltoztatására szokták használni az adott raszter pozíció esetén. Megjegyzendő, hogy a mélység kimeneti sémát és a több megjelenítési célt nem minden árnyalási modell támogatja. Séma Leírás COLORn Szín az n-ik megjelenítési célhoz DEPTH Mélység érték Ahol n egy egész szám. Például: COLOR0, stb. 17

3.6 Saját programba való ágyazás Árnyaló kód főprogramba való beépítéséhez a D3DX Effect függvényeit fogjuk felhasználni. A D3DX a Direct3D segédkönyvtárait foglalja magába, beleértve az Effect komponenst is. Egy effect fájl assembly vagy HLSL nyelvű árnyalási kódot tartalmaz. Az árnyalási program egy.fx vagy.fxl kiterjesztésű állomány, ami egy vagy több Techniques-nek nevezett effektet tartalmaz. Egy tipikus effect fájl a következő képen nézhet ki: float4x4 view_proj_matrix; texture g_imgtex0; sampler SamplerTex0 = sampler_state Texture = <g_imgtex0>; MinFilter = Linear; MagFilter = Linear; MipFilter = Linear; ; struct VS_INPUT float4 pos float4 tex0 ; :POSITION; :TEXCOORD0; struct VS_OUTPUT float4 pos :POSITION; float4 tex0:texcoord0; ; VS_OUTPUT VertScene( VS_INPUT In ) VS_OUTPUT Out = (VS_OUTPUT) 0; Out.pos = mul(in.pos, view_proj_matrix); Out.tex0 = In.tex0; return Out; float4 PixScene( VS_OUTPUT In ) : COLOR return tex2d( SamplerTex0, In.tex0); technique RenderScene pass P0 VertexShader = compile vs_1_0 VertScene(); PixelShader = compile ps_1_0 PixScene(); 18

Miután eltároltuk az effeteket egy fájlban, szeretnénk azt a programunkban használni. Első dolgunk a fájl betöltése és az alapján az effect létrehozása, amihez a D3DXCreateEffectFromFile() API függvényt használjuk. Ezt követően megfelelően feltöltünk minden konstanst: g_peffect->setmatrix( "view_proj_matrix", &mviewprojection ); g_peffect->settexture("g_imgtex0", g_ptexture ); Majd beállítjuk a kívánt technikát, és kirajzoltatjuk a geometriát: g_peffect->settechnique( "RenderScene" ); g_peffect->begin( &cpasses, 0 ); // Az első (és egyetlen) technikánk kiválasztása g_peffect->beginpass( 0 ); // Alakzat kirajzolása pd3ddevice->setfvf( D3DFVF_CUSTOMVERTEX ); pd3ddevice->setstreamsource (0, g_pvb, 0, sizeof(customvertex)); pd3ddevice->drawprimitive (D3DPT_TRIANGLELIST, 0, 2); g_peffect->endpass(); g_peffect->end(); Lehetőség van a HLSL kódunk D3DX Effect nélküli integrációjára is. Ez némi többletmunkával jár, amit eddig az Effect interfész vállalt magára. Ennek ismertetésére nem tér ki jelen dokumentum. Részletesen megtalálható a DirectX SDK[3] HLSLwithoutEffect nevű példaprogramjában. Érdemes figyelemmel kísérni a DirectX SDK[3] frissítéseket, ugyanis így hasznos D3DX segédeszközökhöz és kiforrottabb, optimalizáltabb HLSL fordítókhoz juthatunk hozzá. 19

4 Képfeldolgozás [2][3] alapján 4.1 Képtérben történő műveletek 4.1.1 Pont alapú transzformációk Átviteli függvény: g(x,y) = f(x,y) Eredeti képpont visszanyerése Az eredeti képünk egy textúrában van eltárolva. A textúrához egy mintavételezőn keresztül férünk hozzá. Egy pixelt a textúrán a textúra koordináta azonosít. Tehát egy adott pixelhez tartozó színértékeket a tex2d() függvénynek átadott mintavételező és textúrakoordináta alapján kapható meg. Ennek megfelelően az eredeti képet előállító pixel árnyaló kódja: // Original Image ([A4]. Ábra) float4 PixScene( VS_OUTPUT In ) : COLOR return tex2d( SamplerTex0, In.tex0); Invertált kép Átviteli függvény: g(x,y) = (Maximális érték) - f(x,y) Hagyományos képfeldolgozás esetén a maximális érték 255, mivel az egyes színkomponenseket általában egy 8 bites egész szám ábrázol. A HLSL esetén minden színkomponenst egy 32 bites lebegőpontos szám azonosít, aminek az értéktartománya 0.0-tól 1.0-ig kell hogy terjedjen, különben csonkításra kerül. Tehát egy pixel negáltja a következő képen kapható: // Inverted Color ([A5]. ábra) float4 InvertScenePS( VS_OUTPUT In ) : COLOR return 1.0f - tex2d( SamplerTex0, In.tex0); 20

[A4]. Ábra Eredeti kép [A5]. Ábra Invetált kép Szürkeárnyalatos kép Egy színes kép szürkeárnyalatos megfelelőjét megkapjuk, ha színösszetevőnként vett összeget elosztjuk hárommal. Fontos megjegyezni, hogy a pixel alfa csatornáját ne változtassuk meg. Erre szolgál a (float3) típus konverzió, így csak az első három komponensen (r,g,b) végezzük el a műveleteket. // Grayscale Image ([A6]. Ábra) float4 GrayScalePS( VS_OUTPUT In ) : COLOR // Hagyományos megoldás //float4 c = tex2d( SamplerTex0, In.tex0); //return (float4)((c.r + c.g + c.b)/3.0f); // Tömörebb megoldás return dot( (float3)tex2d( SamplerTex0, In.tex0), 0.3333333) ; [A6]. Ábra Szürkeárnyalatos kép 21

Egyedi átviteli függvények Képletekkel nehezen leírható átviteli függvények és időkritikus alkalmazások esetén hasznos minden egyes bemenő értékhez előre kiszámítani a neki megfelelő kimenő értéket. Ezek után a későbbiekben már csak elő kell keresni a kimenő értéket. Ezt a technikát használva gyorsíthatunk meglévő kódot és utasításokat spórolhatunk meg, amely a kötött utasításhosszal rendelkező árnyaló nyelv esetén fontos lehet. Az előre kiszámított értékeket egy 1D textúrában tárolunk, és a címzéshez az adott pixel szürkeárnyalatos értékét használjuk fel. Példaként álljon itt a Sepia átviteli függvény: // Sepia Transfer function ([A7]. Ábra) float4 SepiaPS( VS_OUTPUT In ) : COLOR float3 lut = dot( (float3)tex2d( SamplerTex0, In.tex0), 0.3333333) ; return tex2d(samplersepiatex,lut); Pont alapú küszöbölés Átviteli függvény: g(x,y) = (maximális érték) Ha f(x,y) > Küszöb érték g(x,y) = (minimális érték) Ha f(x,y) <= Küszöb érték Az esetünkben a maximális érték 1, a minimális pedig 0. // Threshold ([A8]. Ábra) float4 ThresholdPS( VS_OUTPUT In ) : COLOR float gray = dot( (float3)tex2d( SamplerTex0, In.tex0), 0.3333333) ; if(gray > g_userinput) gray = 0.0f; else gray = 1.0f; return (float4)gray; [A7]. Ábra Sepia stílus [A8]. Ábra Küszöbölésen átesett kép 22

4.1.2 Ablak vagy maszk alapú transzformációk A kép adott pixelét a környezetében lévő pixelek függvényében módosítjuk, pixelről pixelre haladva. A pont alapú műveletekhez hasonlítva idő- és számításigényesebb, de hatékonyságuk is jelentősebb. Maszkok használata: A forrás kép minden pixelére egy maszkot helyezünk, úgy hogy annak origója az adott pixelre essen A forrás kép maszk alatti pixeleit megszorozzuk a maszkban szereplő súlyokkal Az eredmény a súlyozott pixelek összege vagy azok skálázott értéke A megvalósításhoz ki kell számítani a szomszédos pixelekhez tartozó textúrakoordináta eltolást. A textúratér 0-tól 1-ig terjed. A [0,0] a kép bal alsó sarkát, az [1,1] pedig a jobb felső sarkát azonosítja. Amennyiben a kép szélességét az imagewidth, a kép magasságát az imageheight változó reprezentálja, az eltolások a következő képen számítható: float width = 1.0f/(float)imageWidth; float height= 1.0f/(float)imageHeight; Ezek alapján tetszőleges méretű, alakú maszkot hozhatunk létre. Például egy 3x3-as maszk eltolási textúrakoordinátái a következőek: [-w,-h] [ 0,-h] [ w,-h] [-w, 0] [ 0, 0] [ w, 0] [-w, h] [ 0, h] [ w, h] A következő átlagoló szűrőt megvalósító programban az offsetsps tömb tárolja az említett eltolásokat. Természetesen a maszk közepét kivéve, ugyanis az az eredeti pixel. // Indexek értelmezése // 0 1 2 // 3 P 4 // 5 6 7 float4 offsetsps[8]; // Átlagoló szűrő ([A9]. Ábra) // 1 1 1 // 1 1 1 // 1 1 1 float4 AveragePS( VS_OUTPUT In ) : COLOR float4 texcoords; float4 texsamples[8]; for(int i=0; i<8; ++i) // Szomszedos pixel tex. koord. kiszamitasa texcoords = In.tex0 + offsetsps[i]; // Szín kinyerese texsamples[i] = tex2d( SamplerTex0, texcoords); float4 avg = 0.0f; 23

for(int i=0; i<8; ++i) // Pixel környezetének hozzáadása avg += texsamples[i]; // Pixel hozzáadása avg += tex2d( SamplerTex0, In.tex0); avg /= 9.0f; return avg; A gyorsabb kód elérése érdekében célszerű elvonatkoztatni a maszkok elméleti definícióitól és pl. egy általános 3x3-a maszk függvény helyett több speciális függvényt megírni. Általános megvalósítás esetén 8 szorzás és 7 összeadás művelet szükséges, összevonásokat használva 6 szorzást spórolunk meg a Kirsch szűrő esetén. // Kirsch ([A10]. Ábra) // 5 5 5 // -3 0-3 // -3-3 -3 float4 KirschPS( VS_OUTPUT In ) : COLOR float4 texcoords; float4 texsamples[8]; for(int i =0; i < 8; i++) texcoords = In.tex0 + offsetsps[i]; texsamples[i] = tex2d( SamplerTex0, texcoords); texsamples[i] = dot( (float3)texsamples[i],.333333f); float4 ret; ret = 5 *(texsamples[0] + texsamples[1] + texsamples[2]); ret -= 3 *(texsamples[3] + texsamples[4] + texsamples[5] + texsamples[6] + texsamples[7]); return ret; [A9]. Ábra Átlagoló szűrő hatása [A10]. Ábra Kirsch szűrő hatása 24

4.1.3 Teljes képre vonatkozó transzformációk Az eredmény pixelérték olyan műveleten eredményeképpen jön létre, amely két vagy több képet használ fel. Általában az eredmény pixel ugyanabban a helyzetben marad. Művelet Összeadás Kivonás Szorzás, osztás Átlagolás Vagy (OR) És (AND) Hatása Információk kombinálása Változásdetektálás Fényesség beállítás Képminőség javítás Kép adott részének hozzáadása Kép adott részének kivágása HLSL megvalósítása nem okozhat problémát. Két kép esetén mindössze annyi a teendőnk, hogy két mintavételezőt deklarálunk a két képnek, egyenként kiolvassuk a pixelértékeket és elvégezzük rajtuk a kívánt műveletet. 4.1.4 Geometriai transzformációk Geometriai transzformációk alatt a pixelek eltolását, elforgatását, skálázását értjük. Ezen transzformációk célja kiszámítani, hogy miként nézne ki az adott kép, ha más kamerapozícióból készítettük volna a képet. A transzformációk eredménye könnyen megkapható mindössze annyi a feladatunk, hogy a virtuális kameránkat eltoljuk vagy épp más orientációba helyezzük. Ezen műveletek a Direct3D általános programozásához tartoznak és nem közvetlenül a grafikus kártya HLSL nyelvű programozásához, így itt nem kerül részletesebb tárgyalásra. 4.2 Frekvencia tartományban történő műveletek A pixel árnyaló 2.0-ás verziójától kezdve elérhetővé vált a frekvencia tartományba való áttérés lehetősége, a megnövekedett programhossznak és a több regiszternek köszönhetően. A Fast Fourier transzformáció valós idejű megvalósítását [2]-es referenciában megtalálhatjuk. 25

5 Értékelés A dokumentum egyedülálló és hiánypótló abban a tekintetben, hogy nem áll rendelkezésre a dokumentum írásának pillanatában magyar nyelvű szakirodalom. A mű felhívja a figyelmet a magas szintű árnyaló nyelvek fontosságára és aktualitására. Továbbá lépésről lépésre részletezi a HLSL nyelvet, azzal a céllal, hogy az olvasó is képes legyen egyedül megvalósítani programozási elképzeléseit. Konkrét képfeldolgozási példákon keresztül mutatja be a gyakorlati használhatóságot. A dolgozat fő célját elérte, ami az volt, hogy felkeltse a figyelmet a jövő technikáira és az érdeklődő minimális erőfeszítések árán képes legyen egy "Hello világ!" HLSL program megírására. Jelen dolgozat nem tudott a teljességre törekedni. Egyrészt a szerző egy régebb óta fejlesztett projekttel volt elfoglalva, másrészt a dolgozat befejezésének pillanatában jutott olyan kurrens idegen nyelvű dokumentum[5] birtokába, amelyre már nem jutott idő feldolgozni. 6 Magasszintű árnyaló nyelvek jövője Egyértelműen kijelenthető, hogy új korszak kapujához érkeztünk. Oda, ahol a CPU és a GPU vállvetve dolgozik programjaink futtatásán. Az árnyaló nyelvek 3.0-ás verziójának megjelenésével már nem is annyira a jövőről beszélünk, hanem a jelenről. 2005 augusztusában Los Angeles-be megtartott nemzetközi számítógépes grafikai konferencián [4] szó volt a grafikus hardver általános célú számításokra történő használásáról. Mostanra pedig mindenki számára elérhetővé tették az interneten. Kellemes videókártya programozást és a témában való elmélyülést [5] kíván a szerző. 7 Elérhetőség A szerző bármilyen észrevételt szívesen fogad a következő címen: Szőke Imre: szokeimre@freemail.hu A dolgozat és a hozzá kapcsolódó alkalmazás honlapja a következő címről érhető el: http://www.starfleet.hu/szokeimre/hlsl/index.htm 26

8 Irodalomhivatkozások [1] Craig Peeper and Jason L. Mitchell, "Introduction to the DirectX 9 High Level Shading Language" in ShaderX 2 - Introduction And Tutorials with DirectX 9.0, Wolfgang Engel editor, Wordware, September 2003. http://www.ati.com/developer/shaderx2_introductiontohlsl.pdf (2005-11-05) [2] Jason L. Mitchell, Marwan Y. Ansari and Evan Hart, "Advanced Image Processing with DirectX 9 Pixel Shaders" in ShaderX 2 - Shader Tips and Tricks, Wolfgang Engel editor, Wordware, Sept. 2003. http://www.ati.com/developer/shaderx/shaderx2_advancedimageprocessing.pdf (2005-11-05) [3] Jason L. Mitchell "Image Processing with Pixel Shaders in Direct3D" http://mirror.ati.com/developer/shaderx/shaderx_imageprocessing.pdf (2005-11-06) [4] SIGGRAPH2005 The 32nd International Conference on Computer Graphics and Interactive Techniques http://www.siggraph.org/s2005/ (2005-11-06) [5] SIGGRAPH 2005 GPGPU COURSE, SIGGRAPH 2005, Los Angeles, August 2005 GPGPU : General Purpose Computation On Graphics Hardware http://www.gpgpu.org/s2005/fullcoursenotes.pdf (2005-11-06) [6] Microsoft. DirectX 9 Software Development Kit http://msdn.microsoft.com/directx/ (2005-11-05) [7] Dr. Szirmay-Kalos László, Antal György, Csonka Ferenc, Háromdimenziós grafika, animáció és játékfejlesztés, Computerbooks, 2003. 9 Ábrajegyzék [A1 3] DirectX 9 Software Development Kit [6] Help ábrái [A4 10] Saját programból készült képernyőmentés 27