Ez a (kissé idétlenre sikeredett) cím az omni fényekkel együtt használható shadow mapekről szól. És hogy miért érdemes erről írni... Szerintem joggal tekinthető ez a legbonyolultabb esetnek.
Az omni fényforrások egyik tulajdonsága, hogy a tér minden irányába indulnak belőlük fénysugarak vagyis a fényforrás a teljes 360 fokos térszöget látja a környezetéből. Ez a tény -szokás szerint- a textúrázást alaposan megnehezíti és némi kutatás után rájövünk, hogy ez a probléma közös a dinamikus environment mapping témakörével vagyis hogyan képezzük le a teljes környezetet. Több lehetséges megoldás közül kiemelnék hármat:
- sphere mapping - ezen esetet nem tárgyalom, mert a vetítés rendkívüli torzítást igényel. Bár kétségtelen előnye, hogy mindössze egy textúrára az egész környezet leképezhető.
- dual paraboloid mapping
- cube mapping
Most pedig következzen a 2. és 3. pontban említett típusok összehasonlítása.
Dual paraboloid mapping | Cube mapping | |
A környezetet Vetítés Mintavételezés Torzítás Szűrés | 2 textúrával fedi le paraboloid "visszavetítés" + térfél választás jelentős a 2 textúra találkozásánál hiányzik | 6 textúrával fedi le hagyományos perspektív egyszerű cubemap közepes, főként a texturák találkozásánál cubemap szűrés |
Eddig úgy tűnik, hogy a cube mapping áll nyerésre leszámítva a 6 textúrát. Sőt ha belegondolunk a sm4.0 nyújtotta lehetőségekbe, akkor még az sem okoz igazán gondot.
A leglényegesebb gond azonban az, hogy potenciálisan költséges nagy méretű cubemapből mintavételezni. Ennek kiküszöbölésére dolgozták az ún. virtual cube mapet. Az egész trükk azon alapul, hogy a cubemap textúráit egy egyszerű megoldással kiterítik egy 2d textúrába, ahonnan viszont már gyors a mintavételezés. A kiterítésért cserébe szűrési hibák lépnek fel ill. egy textúra indirekció válik szükségessé és plusz egy textúra mintavétel. Az első mintavételezés egy kisméretű cubemapből történik, amely textúra koordinátákat tartalmaz és ezekkel férünk hozzá a következő mintavételezés során a kiterített valódi adatokhoz. Vcm esetén természetesen elveszítjük a cubemap szűrést.
Megemlítendő még, hogy a paraboloid mappingnek is van egy komoly hátránya. Jól tesszellált modelleket, jól tesszellált felületekre lehet vele vetíteni komolyabb vizuális hibák nélkül. Ez a vetítés paraboloid jellegéből fakad hiszen két vertex között lineáris interpoláció megy végbe, amely helytelen eredményhez vezet. Természetesen a vetítés és a mintavételezés is átvihető fragment oldalra és ezzel a probléma megszűnik "némi" teljesítménycsökkenés árán.
Most vessünk pár pillantást a mintavételezésre közelebbről.
Ez a dpm egyik térfelének a mintavételezése:
DP3 len_pos, pos, pos;
RSQ inv.x, len_pos.x;
MUL pos, pos, inv.x;
RCP len_pos, inv.x;
ADD pos_tex, pos, hemi0;
RCP inv.z, pos_tex.z;
MUL pos_tex.x, pos_tex.x, inv.z;
MUL pos_tex.y, pos_tex.y, inv.z;
MUL pos_tex.z, len_pos.z, light_pos.w;
MAD result.texcoord[1], pos_tex, half1, half0;
A felső pár sorban lévő normalizálást leválthatjuk egy textúra mintavételezésre, de még így kb. 8*2 utasítás lesz összesen a mintavételezéshez szükséges textúra koordináták előállítása. A mintavételezés pedig kb. 2 db 1024es vagy nagyobb textúrából történik majd.
A cubemap mintavételezés jóval egyszerűbb. A fényvektort ilyenkor nem is szükséges normalizálni, amellyel majd mintát veszünk a cubemapből. Ezután jön a valódi mintavételezés. Összeszámolva ez kb. 3 utasítás a teljes környezet leképezésére. A kiterített cubemap azonban tekintélyes méretű lehet: 6 db 1024es textúra egy 3*1024 x 2*1024es textúrába csomagolva. Ráadásul még egy hibát is tapasztaltam: a cubemap nem lehet akármilyen kicsi, mert a lineáris interpoláció a textúra koordinátákat a face-k szélen elrontotta az esetemben.
Lehetséges még közvetlen cubemapbe renderelés is azonban ilyenkor a mélységi összehasonlítás nem fog működni vagyis nekünk kell fragment programból megoldanunk. Sm4.0 gpuk már hardveresen meg tudják ezt oldani.
Mindent összevetve számos pro és kontra szól mindkét megoldás mellett és ellen vagyis jelenleg nem tudok dönteni. A vcm mellett szól a kevés utasítás, ellene pedig a nagy textúra és a körülményes renderelés. A dpm mellett szól a kis textúra viszonylag egyszerű renderelés ellene a sok utasítás...
Kiegészítés junius 5-én:
kimaradt pár utasítás a vcm megvalósításból:
Elő kell állítani azt a bizonyos r komponenst a mélységi összehasonlításhoz. Ehhez szükség van 2 dp4-re, 1 rcp-re és 1 mulra vagyis 3 utasításból lesz 7, amiből 3 nem "olcsó". Még a végén kiderül, hogy a dpm a jobb...