Most hogy stabilnak mondható az enginem itt az ideje megoldani a materialok problémakörét. Kiindulási alapnak a q3 shader kezelését veszem hiszen számos példán tapasztalhattuk, hogy még a mai napig jól működő rendszer annak ellenére, hogy a renderelési megvalósítása már erősen elavult.
A q3 shader nem más, mint egy egyszerű scriptfile. Ez tartalmazza az adott felület megjelenítéséhez szükséges összes információt a felhasznált textúrákon át a vertexek animálásáig (érdekesség: a q3 engine-ben használt méretarány a wolfenstein korából származik: 8 egység egy láb hosszt jelent).
A shader utasítások több típusra oszthatók:
- általános
- állapot specifikus
- q3map specifikus és
- szerkesztő specifikus.
Utóbbi kettő az ingame renderelést közvetlenül nem befolyásolja. A többi típus esetén fontos tudnunk, hogy a végső eredményt befolyásolja az utasítások sorrendje! Az utasítások némelyike változtatható paraméterek transzformálását végzi, amelyet az alábbi hullámfüggvényekkel írja le:
- szinusz(sin) - szinusz hullám -1 és 1 tartományban
- háromszög(triangle) - háromszög formáju hullám, egyenes felfutási és lefutási ággal 0 és 1 tartományban
- négyszög(square) - négyszög impulzus, mely -1 és 1 tartomány értékeit veszi fel átmenet nélkül
- fűrészfog(sawtooth) - egyenes felfutás 1 értékig aztán 0-ra zuhan
- fordított fűrészfog(inversesawtooth) - mint az előző csak felfutás helyett lefutási forma jellemzi
Ezeket a függvényeket a hullámtanból ismert tulajdonságok befolyásolják:
- base
- amplitude
- phase
- freq
Az általános csoportba az adott shaderre egyszer ható utasítások tartoznak, amely közül a fontosabbak a következők.
cull: a következő paraméter megadja, hogy a felület melyik oldala kerüljön eldobásra (front, back) vagy ne legyen eldobás (disable, none).
fogparms: 4 paramétert vár, amelyek közül az első 3 a köd színét jelenti, az utolsó azt a távolságot jelenti, amelytől távolabb a köd már teljesen átlátszatlan.
Az állapot specifikus utasításokból tetszőleges számú lehet, amelyeket a map parancsok osztanak nagyobb egységekre. Úgy is felfoghatjuk, hogy minden egyes map parancs megfelel egy textúrázási lépésnek. Az adott felületet tehát annyiszor rendereli, ahány map parancsot tartalmaz a shader. Emiatt nagyon fontos (volt) a helyes blendezés és sorrend és a mennyiség körültekintő megválasztása!
map: egy paramétert vár, ami a textúraként felhasználni kívánt kép elérési útvonala és neve. A texture wrap repeat.
clampmap: egy paramétert vár, ami a textúraként felhasználni kívánt kép elérési útvonala és neve. A texture wrap clamp.
animmap: max. 9 paramétert vár. Max. 8 db textúra lejátszását teszi lehetővé. Az első szám a lejátszás frekvenciáját jelenti.
rgbgen: a felület vertexeihez tartozó színek rgb komponenseinek forrását jelzi. Ha a következő paraméter
- identitylighting, akkor a szín fehér vagy szürke lesz az overbright beállításoktól függően
- identity, akkor a szín fehér lesz
- vertex, ekkor a vertexhez tárolt szín kerül felhasználásra
- oneminusvertex, az előző eset inverze
- lightingdiffuse, diffúz árnyalás eredménye a szín
- wave, ekkor egy hullámfüggvény nevét és paramétereit kell megadnunk többi paraméterként. Az eredmény színt a hullámfüggvény szolgáltatja.
alphagen: a felület vertexeihez tartozó színek alfa komponensét várja float paraméterként vagy a portal szót.
tcgen: a felület vertexeihez tartozó textúra koordináták forrását jelzi. Ha a következő paraméter
- base, akkor a vertex textúra koordinátáit használja fel a renderelő
- lightmap, akkor a vertexhez tartozó lightmap textúra koordinátáit használja fel a renderelő
- environment, akkor a vertexhez tartozó normálok alapján számolja ki a textúra koordinátákat egy environment maphez
- vector, akkor 6 db float következik. Ekkor a vertexek poziciójának és az első számhármas szorzatának eredménye lesz textúra koordináta s komponense. A t komponens hasonlóan kerül kiszámításra csak a második számhármas segítségével.
tcmod: a textúra koordináták transzformálását végző utasítás. A következő paraméter egy az alábbi nevek közül:
- rotate, a következő paraméter adja meg a forgás irányát és mértékét.
- scale, amely 2 paramétert vár
- scroll, amely szintén 2 paramétert vár
- stretch, egy hullámfüggvényt vár paraméterként
- turb, amely egy hullámfüggvény paramétereit(!) várja
- transform, egy 2x3-as mátrixot vár és ezzel szorozza be a textúra koordinátákat
blendfunc: ha az utasítás után egy paraméter következik, akkor annak egy előre foglalt szónak kell lennie: add, blend vagy filter. A filter egy speciális eset, amely lightmappel blendel. A blendelést megadhatjuk közvetlenül is két paraméterrel, amelyek az OpenGLből ismert szavak lehetnek.
depthfunc: a következő a mélységi tesztet állítja
alphafunc: a következő paraméter az alábbi szavak egyike lehet:
- GT0, vagyis nagyobb, mint nulla
- LT128, vagyis kevesbb, mint 128
- GE128, vagyis nagyobb vagy egyenlő 128nál
depthwrite: ez a szó jelzi, ha az adott felület a mélység bufferbe is renderelésre kerül