Vizualizációs algoritmusok csoportosítása Direkt térfogat-vizualizáció Csébfalvi Balázs Irányítástechnika és Informatika Tanszék Budapesti Műszaki és Gazdaságtudományi Egyetem Indirekt vizualizáció: Átmeneti reprezentációra van szükség Direkt vizualizáció: Közvetlenül a diszkrét adatot dolgozzuk fel Képsorrendi (image order) megközelítés a feldolgozást a pixelek sorrendjében végezzük Objektumsorrendi (object order) megközelítés a feldolgozást a voxelek sorrendjében végezzük Hibrid megközelítés ötvözi az objektumsorrendi és a képsorrendi módszerek előnyeit 2 / 81 Képsorrendi megközelítés - térfogati sugárkövetés Belső struktúrák megjelenítése Nincsenek analitikusan definiált objektumok A felületeket egy diszkrét implicit függvény reprezentálja Szeletelés: a térfogat keresztmetszetét egy adott színkódolással megjelenítjük szeletelés Szükség van a folytonos implicit függvény rekonstrukciójára (approximáció/interpoláció) A pontos felületi normálisok a diszkretizálás során elvesznek Az árnyaláshoz becsülni kell a normálvektorokat Szintfelület: nem átlátszó vagy áttetsző felületek online rekonstrukciója A különböző anyagok elnyelik a kibocsátott vagy visszavert fényt 3 / 81 áttetsző anyag szintfelület 4 / 81 Ray Tracing vs. Ray Casting A sugárprofil definíciója A klasszikus sugárkövetés rekurzív (többszörös visszaverődések modellezése) Mért térfogati adatokban általában csak az elsődleges sugarakat (viewing ray primary ray) követjük mivel a pontatlan normálvektorok akkumulált hibát eredményeznek Távolságtranszformációval konvertált geometriai modellek esetén a becsült gradiensek elég pontosak a rekurzív sugárkövetéshez Térfogati adat: skalármező a 3D térben f 1 ( x) R, x Sugár: félegyenes Minták a sugár mentén: sugárprofil R 3 1 r( t) R, t R 3 1 1 f ( r( t)) R, t R 5 / 81 6 / 81 1
Sugárprofilok leképzései Első ütközés (first-hit ray casting) MIP Alpha-blending Röntgen Első ütközés 7 / 81 8 / 81 Röntgen-szimuláció MIP - Maximum Intensity Projection 9 / 81 1 / 81 Akkumuláció - Alpha-blending Többszintű térfogat-vizualizáció Szegmentálás Az egyes tartományokhoz különböző kompozitáló operátorokat használunk 11 / 81 12 / 81 2
Stílus átviteli függvények Térfogat-vizualizációs integrál Illusztratív megközelítés Az egyes tartományokhoz megjelenítési stílust rendelünk A sugár parametrikus egyenlete: Térfogat-vizualizációs integrál: t max t ( s )ds I Diszkrét közelítés: N r( t ) o d t I( t )e dt I c( ti ) ( t ) (1( t )) i i i1 j j 13 / 81 14 / 81 Rekurzív kiértékelés Back to front: C out c( t ) ( t ) C i ( 1 ( t Front to back: akkumulált opacitás pufferre van szükség abbahagyjuk, ha az akkumulálódó opacitás már elért egy küszöbértéket (early ray termination) i in i )) Klasszikus Ray Casting Marc Levoy 1988 1. C(i) és α(i) értékeit az átviteli függvény (Transfer Function) határozza meg 2. Ray casting, interpoláció 3. Kompozitálás 15 / 81 16 / 81 1. lépés: osztályozás, árnyalás 2. lépés: Sugarak bejárása Árnyalás: f(i) C(i) átviteli függvény Phong modell normálvektor: becsült gradiens Osztályozás: f(i) α(i) Levoy 88: moduláció a gradiens nagyságával a jól definiált átmeneteket hangsúlyozza 17 / 81 18 / 81 3
Sugarak bejárása, interpoláció Interpoláció - Újramintavételezés Voxel-alapú vs. cella-alapú bejárás Trilineáris (interpoláció a cellán belül) vs. bilineáris (interpoláció a cellák lapjain) Trilineáris interpoláció: 1. 4 új minta x irányban (interpolált négyzet) 2. 2 új minta y irányban (interpolált vonal) 3. 1 új minta z irányban (interpolált pont) Egységnyi vs. változó lépésköz: A kompozitálás különböző eredményt ad opacitás-korrekció 19 / 81 2 / 81 3. lépés: kompozitálás Back-to-Front (B2F): Out i =In i (1 - α i ) + C i α i, In i+1 =Out i példa: Voxel i: C i = piros, α i =3%, In i = fehér Kompozitálás után: 7% fehér + 3% piros Front-to-Back (F2B): Akkumulált szín: C akk = C akk + (1 - α akk ) C i α i Akkumulált opacitás: α akk = α akk + (1 - α akk ) α i Összehasonlítás Back-to-Front (B2F) két voxelre: Háttér: In 1. voxel: Out =In (1 α ) + C α = In 1 2. voxel: Out 1 =In 1 (1 α 1 ) + C 1 α 1, In i+1 = In (1 α )(1 α 1 ) + C α (1 α 1 )+ C 1 α 1 Front-to-Back (F2B) két voxelre: Inicializálás: C akk =, α akk = 2. voxel: C akk = C akk + (1 - α akk ) C 1 α 1 = C 1 α 1 α akk = α akk + (1 - α akk ) α 1 = α 1 1. voxel: C akk = C 1 α 1 + (1 α 1 ) C α α akk = α 1 + (1 α 1 ) α Háttér: C akk = C 1 α 1 + (1 α 1 ) C α + (1 α 1 )(1 α ) In 21 / 81 1-(α 1 +(1-α 1 ) α ) 22 / 81 Opacitással modulált interpoláció Preklasszifikáció vs. Posztklasszifikáció Interpoláció opacitásmoduláció nélkül 1.5 1 Interpoláció opacitásmodulációval 1.5 1 23 / 81 Preklasszifikáció A szín és opacitás értékeket a voxelekhez rendeljük hozzá A mintavételi pontokban ezeket az értékeket interpoláljuk (opacitás-moduláció) Posztklasszifikáció a sűrűségértékeket (és a gradienseket) interpoláljuk A mintavételi pontokhoz rendelünk színt az átviteli függvény szerint A mintavételi pontokat árnyaljuk az interpolált gradiens alapján 24 / 81 4
Preklasszifikáció vs. Posztklasszifikáció Preklasszifikáció vs. Posztklasszifikáció 25 / 81 26 / 81 Átviteli függvények Transfer functions Átviteli függvények Transfer functions Input: sűrűség gradiens (elsőrendű deriváltakból) görbület (másodrendű deriváltakból) pozíció (szegmentáló maszk alapján) Output: szín (pl. RGB formátum) opacitás 27 / 81 28 / 81 Fuzzy átviteli függvények Sugárkövetéssel generált képek Feltétel: Minden cellában legfeljebb két anyag keveréke lehet Bázisfüggvények lineáris kombinációja 29 / 81 3 / 81 5
Görbület alapú átviteli függvények Görbület alapú átviteli függvények Hesse mátrix a másodrendű parciális deriváltakat tartalmazza A színeket a Hesse mátrix sajátértékei alapján rendeljük hozzá a voxelekhez κ 1 κ 2 (κ 1 +κ 2 )/2 κ 1 κ 2 31 / 81 32 / 81 Brute-force Ray Casting (B2F) RGB Volume::RayCasting(Vector pos, Vector dir) RGB color_acc; DBL tmin = this->entrypoint(), t = this->exitpoint(); while(t > tmin) Vector sample = pos + dir * t; DBL density = this->resample(sample); // trilinear interpolation Vector gradient = this->resamplegradient(); opacity = OpacityFunction(density, gradient.magnitude()); color = ColorFunction(density) * Shading(gradient); color_acc = c_acc * (1 opacity) + color * opacity; t--; retrun color_acc; 33 / 81 Brute-force Ray Casting (F2B) RGB Volume::RayCasting(Vector pos, Vector dir) RGB color_acc; DBL opacity_acc = ; DBL t = this->entrypoint(), tmax = this->exitpoint(); while(t < tmax) Vector sample = pos + dir * t; DBL density = this->resample(sample); // trilinear interpolation Vector gradient = this->resamplegradient(); opacity = OpacityFunction(density, gradient.magnitude()); color = ColorFunction(density) * Shading(gradient); color_acc += (1 opacity_acc) * color * opacity; opacity_acc += (1 opacity_acc) * opacity; t++; retrun color_acc; 34 / 81 First-Hit Ray Casting Gyorsító módszerek RGB Volume::RayCasting(Vector pos, Vector dir, DBL threshold) DBL t = this->entrypoint(), tmax = this->exitpoint(); while(t < tmax) Vector sample = pos + dir * t; DBL density = this->resample(sample); // trilinear interpolation if(density > threshold) Vector gradient = this->resamplegradient(); color = Shading(gradient); return color; t++; retrun BACKGROUND; 35 / 81 Primitív műveletek optimalizálása SIMD utasításokkal (SSE) Koherencia kihasználása (adat-koherencia, sugár-koherencia, frame-koherencia) Hierarchikus adatstruktúrák (piramis, octree) Üres régiók átugrása Potenciálmezők alkalmazása Hibrid módszerek (PARC Polygon Assisted Ray Casting) GPU implementáció 36 / 81 6
Vektor osztály Vektor osztály SSE utasításokkal struct Vector float x, y, z, w; Vector(float x, float y, float z, float w = ) x = x; y = y; z = z; w = w; Vector operator*(float a) return Vector(x * a, y * a, z * a, w * a); Vector operator+(vector& v) return Vector(x + v.x, y + v.y, z + v.z, w + v.w); Vector operator-(vector& v) return Vector(x - v.x, y - v.y, z - v.z, w - v.w); float operator*(vector& v) return (x * v.x + y * v.y + z * v.z); Vector operator%(vector& v) return Vector(y*v.z-z*v.y, z*v.x - x*v.z, x*v.y-y*v.x); float Length() return sqrt(x * x + y * y + z * z); ; 37 / 81 struct Vector float x, y, z, w; public: Vector operator+( Vector& v ) declspec(align(16)) Vector res; asm mov esi, this mov edi, v movups xmm, [esi] movups xmm1, [edi] addps xmm, xmm1 movaps res, xmm return res; ; 38 / 81 Early ray termination Min/Max Octree RGB Volume::RayCasting(Vector pos, Vector dir) Minden szinten tároljuk a minimális d min és a maximális RGB color_acc; DBL opacity_acc = ; d max sűrűségeket DBL t = this->entrypoint(), tmax = this->exitpoint(); while(t < tmax) A szintfelületet definiáló Vector sample = pos + dir * t; küszöbérték legyen t DBL density = this->resample(sample); // trilinear interpolation Vector gradient = this->resamplegradient(); Megkeressük az adott mintavételi pontot tartalmazó opacity = OpacityFunction(density, gradient.magnitude()); legnagyobb blokkot, melyre color = ColorFunction(density) * Shading(gradient); t < d min vagy t > d max. color_acc += (1 opacity_acc) * color * opacity; opacity_acc += (1 opacity_acc) * opacity; t++; Ezt a blokkot a szintfelület if(opacity_acc >.999) break; biztosan nem metszi, így a sugarat léptetni tudjuk a retrun color_acc; kilépési pontra 39 / 81 4 / 81 Potenciálmező Hibrid gyorsítás Minden cellában tároljuk a legközelebbi felületi pont távolságát Ezzel a távolsággal tudjuk léptetni a sugarat Objektumsorrendi módszerek: könnyű az üres régiókat kezelni relatíve nagy overhead (vetítés, raszterizálás) ritka térfogati adatokra hatékonyabb Képsorrendi módszerek: nehéz az üres régiókat kezelni a sebesség inkább a pixelek mint a voxelek számától függ egyenletes kitöltöttség esetén hatékonyabb Nem hagyunk ki metszéspontot 41 / 81 Hibrid módszerek: rendszerint több lépés (objektum- és képsorrendi) kombinációja a két megközelítés előnyeinek ötvözése 42 / 81 7
Polygon-Assisted Ray Casting Pacázás - Splatting Megkeressük azokat a cellákat, melyeket a szintfelület metsz A cellák lapjait a grafikus hardverrel két mélységi pufferbe (legközelebbi / legtávolabbi) rendereljük A mélységi puffer tartalma alapján meghatározható a sugarak kezdő és végpontja Objektumsorrendi megközelítés A voxeleket sorra egymásután vetítjük a képsíkra Az üres tartományok kezelésének nincs többletköltsége Cache koherencia kihasználása Hátrányok A finom részletek elmosódnak Szintfelület megjelenítésére csak korlátozottan alkalmas A takart tartományokat is ki kell értékelni 43 / 81 44 / 81 Pacázás: alapötlet Pacázás - hatékonyság Az egyes voxelek nem csak egy pixelre vetülnek, hanem több pixelen hagyják a lenyomatukat (footprint kernel) Szétterítjük a voxel értékét a pixeleken Lenyomat (footprint): kiintegrált rekonstrukciós kernel Ha a rekonstrukciós kernel gömbszimmetrikus, akkor a lenyomat kör alakú és független a párhuzamos vetítés irányától A nagy pixel/voxel arányhoz nagyobb lenyomat kell de ez homályossá teszi a képet (blurring) Perspektív vetítésnél a lenyomat ellipszis alakú, de szintén előre kiintegrálható Perspektív vetítésnél az ellipszisek irányát is számításba kell venni 45 / 81 46 / 81 Pacázás Hatáskör (support): a 3D rekonstrukciós kernel által lefedett tartomány Minden voxelhez tarozik egy a voxel értékével súlyozott kernel Minden kernel egy 2D lenyomatot hagy a képen (szín, opacitás) A súlyozott lenyomatok akkumulálódnak a képen Pacázás Hatáskör (support): a 3D rekonstrukciós kernel által lefedett tartomány Minden voxelhez tarozik egy a voxel értékével súlyozott kernel Minden kernel egy 2D lenyomatot hagy a képen (szín, opacitás) A súlyozott lenyomatok akkumulálódnak a képen voxel kernelek footprint kernelek voxel kernelek footprint kernelek 47 / 81 48 / 81 8
Pacázás Hatáskör (support): a 3D rekonstrukciós kernel által lefedett tartomány Minden voxelhez tarozik egy a voxel értékével súlyozott kernel Minden kernel egy 2D lenyomatot hagy a képen (szín, opacitás) A súlyozott lenyomatok akkumulálódnak a képen voxel kernelek Pacázás - előnyök A pacák előre kiintegrálhatók gyors voxelvetítés Előnyök a sugárkövetéshez képest: a voxelek interpolációja a 2D képtérben történik speciális esetben pontosabb (Röntgen szimulációnál analitikus megoldást ad) csak a releváns voxeleket kell feldolgozni (ritka térfogatokra hatékony) nincs szükség az üres régiók kódólására footprint kernelek 49 / 81 5 / 81 Pacázás - implementáció Pacázás - implementáció A térfogati szeletek voxeleihez tartozó kerneleket akkumuláló pufferekben (sheet buffer) adjuk össze Az akkumuláló puffereket elölről hátra (F2B) kompozitáljuk Azokat a szeleteket vesszük, amelyek leginkább párhuzamosak a képsíkkal Adjuk össze az első szelethez tartozó kerneleket térfogati szeletek akkumuláló puffer 51 / 81 52 / 81 Pacázás - implementáció Pacázás - implementáció Az akkumuláló puffert kompozitáljuk a ba Összeadjuk a második szelethez tartozó kerneleket az akkumuláló pufferben térfogati szeletek térfogati szeletek akkumuláló puffer akkumuláló puffer 53 / 81 54 / 81 9
Pacázás - implementáció Pacázás - implementáció Az akkumuláló puffert kompozitáljuk a ba Az akkumuláló puffert kompozitáljuk a ba térfogati szeletek térfogati szeletek pontatlan kompozitálás, a kernelek átlapolódását nem veszi figyelembe akkumuláló puffer akkumuláló puffer 55 / 81 56 / 81 Rekonstrukciós minőség javítása Lenyomatok számítása A mintavételi síkok távolságát csökkentjük A rekonstrukciós kernelt ennek megfelelően szeletenként integráljuk A rekonstrukciós kernel szeleteinek integrálját előfeldolgozással számoljuk ki 57 / 81 58 / 81 Pacázás - implementáció Pacázás perspektív vetítés 1. Minden voxelt a képernyő-koordinátarendszerbe transzformálunk (a z koordináta reprezentálja a képsíktól mért távolságot) 2. Vödrös rendezés a transzformált z koordináta szerint minden akkumuláló pufferhez tartozik egy vödör 3. A takarási térképet (occlusion map) nulla opacitásra állítjuk 4. Minden akkumuláló pufferre F2B sorrendben Minden lenyomatra Ha a lenyomat által lefedett pixelek még áttetszők A lenyomat raszterizálása és kompozitálás A takarási térkép aktualizálása Perspektív vetítésnél a lenyomat nem kör, hanem ellipszis alakú Lineáris transzformációra és a prekalkulált 2D lenyomat újramintavételezésére van szükség 59 / 81 6 / 81 1
Pacázás 1D lenyomattal Elliptikus paca 1D lenyomattal Kihasználva a szimmetriát a lenyomatot egy 1D tömb reprezentálja Ki kell számítani a középponttól vett távolságot (a négyzetgyök költséges művelet) A tömböt úgy töltjük fel, hogy azt a sugár négyzetével lehessen címezni: r 2 x,y = (x x ) 2 + (y y ) 2 A sugarak négyzetét a raszterizálás során inkrementálisan lehet számítani: r 2 x+1,y = r 2 x,y +2(x x )+1 Ugyanazt az 1D tömböt használjuk mint a kör alakú pacák esetén A sugár négyzetét az ellipszis egyenletéből származtatjuk: r 2 x,y = a(x x ) 2 + b(y y ) 2 + c(x x )(y y ) A sugár négyzetét itt is lehet inkrementálisan számolni: r 2 x+1,y = r 2 x,y + 2a(x x ) + a + c (y y ) 61 / 81 62 / 81 Numerikus hiba Pacázás - összefoglalás Objektumsorrendi megközelítés Az árnyalást a voxelekre számítjuk ki (preklasszifikáció) Interpoláció gömbszimmetrikus kernellel (a trilineáris kernel nem lenne hatékony) Sablon alapú voxelvetítés A kompozitálás akkumuláló puffereken keresztül történik 63 / 81 64 / 81 Pacázással generált képek Preklasszifikáció vs. posztklasszifikáció 65 / 81 66 / 81 11
Az elmosódás oka Az ideális aluláteresztő (low-pass) szűrőt rendszerint egy Gauss-szűrővel közelítjük Preklasszifikációnál a színeket interpoláljuk, ezért a simító hatás miatt homályos lesz a kép Posztklasszifikációnál is van simító hatás, de ezt a küszöbözés (thresholding) kompenzálja Gradiensek becslése Az ideális derivált szűrő a sinc kernel deriváltja Ezt egy Gauss-szűrővel lehet közelíteni: H : a Gauss szűrő deriváltja DH: Centrális differenciák a Gauss szűrővel kombinálva 67 / 81 68 / 81 Pacázás elmosódás nélkül Összehasonlítás A posztklasszifikációs séma adaptálása Az akkumuláló puffereket a sűrűségek interpolációjára használjuk A gradienseket az akkumuláló pufferekből becsüljük központi differenciákkal Az akkumuláló pufferek átmeneti tárolására van szükség A klasszifikációt az akkumuláló pufferen végezzük el preklasszifikáció posztklasszifikáció 69 / 81 7 / 81 Összehasonlítás Pixel szintű műveletek A posztklasszifikációs séma támogatja textúra illetve buckaleképzést preklasszifikáció posztklasszifikáció 71 / 81 72 / 81 12
Hierarchikus pacázás Hierarchikus pacázás Piramis struktúra (teljes octree pointerek nélkül) Minden csomópont tárolja a neki megfelelő cella átlagértékét Egy cella hibája az átlagtól való négyzetes eltérés A megjelenítésnél addig a mélységig megyünk le, amíg a hiba egy rögzített küszöbérték alá nem csökken A gyorsan változó részeket több, a homogén részeket kevesebb csomópont reprezentálja 73 / 81 Fokozatos finomítás (progressive refinement) 74 / 81 Nyírás-Torzítás Shear-Warp Nyírás-Torzítás Shear-Warp Hibrid módszer a képsorrendi és az objektumsorrendi megközelítések ötvözése A vetítést a nyírt térben végezzük el A nyírt térben a szeletek párhuzamosak a képsíkkal Az újramintavételezés 2D műveletté egyszerűsödik (bilineáris interpoláció trilineáris helyett) Az ideiglenesen előállított kép geometriailag torzított, ezért azt egy lineáris transzformációval helyre kell állítani 75 / 81 76 / 81 Nyírás-Torzítás Shear-Warp Nyírás-Torzítás Shear-Warp A vetítő transzformáció faktorizációja: M view = M warp2d M shear3d A 3D nyíró transzformáció: 1 M shear3d 1 s s x y 1 1 77 / 81 A 2D torzító transzformáció egy lineáris egyenletrendszer megoldásaként adódik: 1 sx 1 1 sy M warp2d M view M shear3d M view 1 1 78 / 81 13
Sugársablonok (template) A nyírt térben minden sugarat ugyanazon sablon szerint lehet kiértékelni A sugársablonok az interpolációs súlyokat és a voxelek relatív címeit (offset) tárolják RLE kódolás 79 / 81 8 / 81 Shear-warp módszerrel generált képek 81 / 81 14