GrafikaGyakorloTerfogatVizualizacio

A VIK Wikiből

Ez az oldal a korábbi SCH wikiről lett áthozva.

Ha úgy érzed, hogy bármilyen formázási vagy tartalmi probléma van vele, akkor, kérlek, javíts rajta egy rövid szerkesztéssel!

Ha nem tudod, hogyan indulj el, olvasd el a migrálási útmutatót.


Mintakérdések a Számítógépes grafika és képfeldolgozás tárgy vizsgájára való felkészüléshez

Térfogat vizualizáció

113. Írjon programot, amely egy L(x, y, z) saját színnel és C(x, y, z) opacitásfüggvénnyel jellemzett, a [-1,-1,-1], [1,1,1] kockába zárt térfogatot megjelenít. A szem a [0,0,-2] pontban van, a z irányba néz, az ablak a [0,0,-1] pontban, a z-tengelyre merőlegesen áll és mérete 1x1-s.

  • A getColor függvény egy sugár mentén számítja ki az eredő fényességet. Az ablaktól indulva végighalad a sugár mentén, és ds térközönként lekéri az opacitást és a fényességet, majd a sugár mentén ezeket összegzi. A draw függvény végigmegy az 1x1-es ablakon századonként, és minden pixelen át küld egy sugarat.
  • Ha a sugár mentén ds lépésekkel a szem felé haladva a meglátogatott pontok opacitása, és a kisugárzott fénye, akkor a szembe jutó fény: . Ugyanis, a sugár tulajdonképpen ds vastagságú rétegeken halad át, amik (kis ds esetén) a vastagságukkal arányos fényt bocsátanak ki, illetve az áthaladó fény arányos részét nyelik el. Mivel minden réteg fénye az összes utána lévőn tompítódik, ezért van a nagy szorzatos tényező. Ha ezt az összeget az n-edik tagtól (a szem felől) kezdve akarja az ember iteratívan számolni, akkor kijön a kódban lévő számítás.
float getColor(Vector start, Vector dir) {
  Vector current, entry;
  float ds=0.01;
  float cSum=0, lSum=0;
  dir=dir.normalize();
  entry=start+dir*((-1-start.z)/dir.z);
  for (current=entry; current.z<1; current=current+ds*dir) {
	 lSum=L(current.x, current.y, current.z)*ds*(1-cSum)+lSum;
	 cSum=1-(1-C(current.x, current.y, current.z)*ds)*(1-cSum);
  }
  return lSum;
}

void draw() {
  Vector start(0, 0, -2), dir;
  for (float x=-0.5; x<=0.5; x+=0.01) {
	 for (float y=-0.5; y<=0.5; y+=0.01) {
		dir=Vector(x, y, 1);
		pixel(x, y, getColor(start, dir));
	 }
  }
}

114. Masírozó kockák (marching cubes) algoritmus.

  • Az algoritmussal egy 3D struktúrát lehet megjeleníteni. Van egy függvényünk, ami a 3D tér pontjaihoz egy-egy értéket rendel, és szeretnénk kirajzolni azt a felületet, ahol a függvény adott küszöbértékkel egyenlő (vagyis egy implicit felületet rajzolunk ki). A függvény általában 3D tömbbel (vagyis az adott térközönként vett mintáival) adott.
  • A térre ráteszünk egy kockarácsot, és mindegyik kocka-csúcspontra eldöntjük, hogy a felület melyik oldalán van (vagyis, a függvény ottani értéke nagyobb vagy kisebb, mint a küszöbérték). Ha egy él két végpontja különböző oldalán van a felületnek, akkor ott egy metszéspont van (a metszéspont helye a konkrét függvényértékek alapján interpolálható), ha azonos oldalon vannak, akkor nincs metszéspont. (Itt elhanyagoltuk azt a lehetőséget, hogy egynél többször is metszhet egy élet a felület.)
  • Majd, mindegyik kockába kis felület-darabokat rajzolunk, az alapján, hogy melyik élén van metszéspont. Erre kell egy táblázat, hogy milyen metszéspont-elrendezések esetén milyen felület-darabokat kell rajzolni (lásd pl. a Wikipédia cikkben az ábrát). Az összes kockába rajzolt felületelemek együtt kiadják a felület közelítő képét.
  • Bizonyos metszéspont-eloszlások esetén több különböző módon is felvehetők a felületdarabok. Úgy kell ilyenkor választani, hogy a szomszédos kockák illeszkedjenek egymáshoz.
  • Általában a csúcsokhoz normálokat is rendelnek: a valószerű megjelenítéshez a normál a függvény ottani gradiensvektora kell legyen. Ha a függvény 3D tömbbel van adva, ezt a környező mintákból lehet közelíteni.
  • Wikipédia: masírozó kockák

115. Írjon térfogati modellek megjelenítéséhez fénysugárkövető (segítség: térfogati sugárkövetés, amikor a fénnyel megegyező irányban haladunk) programot. Feltételezheti, hogy a térfogati adatok egy 256x256x256-os voxel tömbben vannak, amely a világ koordinátarendszerben a [0,0,0,], [1,1,1] pontok közötti, a tengelyekkel párhuzamos élű kockának felel meg. A szem a [0.5, 0.5, ] pontban van (segítség: párhuzamos vetítés!), és a z irányba néz. Az ablak közepe a [0.5, 0.5, 0] pontban van, a z irányra merőleges, mérete 1x1. Az képernyő felbontása 256x256 pixel. A voxel színek és opacitások számításánál csak a 0.5 és 0.6 közötti értékeket tekintse nem átlátszónak és a diffúz visszaverődési törvényt adaptálja a szín számításához (segítség: a normálvektort a gradiensből számítsa, az opacitást pedig a gradiens abszolút értékével szorozza). A diffúz BRDF az RGB hullámhosszokon (0.1, 0.4, 0.9). A pontszerű fényforrás a 0,0,0 pontban van, az intenzitása tetszőleges távolságban, helyen és hullámhosszon 1. Feltételezheti, hogy a szokásos vektor és színműveletek rendelkezésre állnak.

-- G - 2008.12.26.