„Számítógépes grafika házi feladat tutorial” változatai közötti eltérés

Rohamcsiga (vitalap | szerkesztései)
Rohamcsiga (vitalap | szerkesztései)
653. sor: 653. sor:
=== Hogyan kövessük a sugarakat? ===
=== Hogyan kövessük a sugarakat? ===


* Az ötlet az, hogy keressük meg a kamerához legközelebbi objektumot, aminek van metszéspontja a sugárral.
Az ötlet az, hogy keressük meg a kamerához legközelebbi objektumot, aminek van metszéspontja a sugárral. Ha találtunk egy metszéspontot, akkor minket a metszéspontja helye és a felületi normál is érdekel (az a vektor, ami merőleges a felületre abban a pontban). Továbbá valahogy azt is jeleznünk kell, ha nem találtunk metszéspontot. Ezeknek az információknak a tárolására egy lehetséges struktúra:
* Ha találtunk egy metszéspontot, akkor minket a metszéspontja helye és a felületi normál is érdekel (az a vektor, ami merőleges a felületre abban a pontban). Továbbá valahogy azt is jeleznünk kell, ha nem találtunk metszéspontot. Erre egy lehetséges struktúra:


<br/> <syntaxhighlight lang="c">  
<br/> <syntaxhighlight lang="c">  
663. sor: 662. sor:
</syntaxhighlight> <br/>
</syntaxhighlight> <br/>


* Ahhoz, hogy eldöntsük, hogy egy objektumnak van-e metszéspontja a sugárral, fel kell írnunk annak az alakzatnak az egyetlenét, és meg kell oldaniuk egy 't' ismeretlenre azt az egyenletet, hogy ha a sugár kiindulási pontjából 't' egységet megyünk előre a sugár irányába, akkor ki fogjuk elégíteni az alakzat egyenletét.
Ahhoz, hogy eldöntsük, hogy egy objektumnak van-e metszéspontja a sugárral, fel kell írnunk annak az alakzatnak az egyetlenét, és meg kell oldaniuk egy 't' ismeretlenre azt az egyenletet, hogy ha a sugár kiindulási pontjából 't' egységet megyünk előre a sugár irányába, akkor ki fogjuk elégíteni az alakzat egyenletét.
** Nagyon sok esetben az okoskodás, pl transzformációk használata ''nagyon'' le tud egyszerűsíteni egy ilyen problémát.  
* Az ilyen egyenletek megoldásához hihetetlen sokat tud segíteni, ha egyszerű ábrákat rajzolsz hozzá.
** A síkbeli (elsőrendű) alakzatok követésekor első fokú egyenleteket fogunk kapni, míg a "görbülő" (másodrendű) alakzatok, pl kör, ellipszis, henger palást, kúp palást, hiperboloid stb... másodfokú egyenletekre vezetnek.
* Nagyon sok esetben az okoskodás, pl transzformációk használata ''nagyon'' le tud egyszerűsíteni egy ilyen problémát.  
** Általában véges objektumokat szoktunk rajzolni, így ha a hozzá tartozó alakzat nem véges, akkor meg kell néznünk, hogy a sugár mely pontokban metszi az alakzatot, és ezekről a pontokról eldönteni, hogy azok a véges részbe is benne vannak-e. Ez utóbbi művelet lehet bonyolultabb mint az előző. Pl. egy háromszög követése lényegesen több ötletet igényel mint egy gömbbé.
* A síkbeli (elsőrendű) alakzatok követésekor első fokú egyenleteket fogunk kapni, míg a "görbülő" (másodrendű) alakzatok, pl kör, ellipszis, henger palást, kúp palást, hiperboloid stb... másodfokú egyenletekre vezetnek.
*** Egy háromszög követésére egy lehetséges algoritmus:
* Általában véges objektumokat szoktunk rajzolni (pl. négyzet), így ha a hozzá tartozó alakzat (pl. sík) nem véges, akkor meg kell néznünk, hogy a sugár mely pontokban metszi az alakzatot, és ezekről a pontokról eldönteni, hogy azok a véges részbe is benne vannak-e. Ez utóbbi művelet lehet bonyolultabb mint az előző. Pl. egy háromszög követése lényegesen több ötletet igényel mint egy gömbbé.
**** ''' Spoiler alert ''' - ha ez kell a házidhoz, akkor ezt a részt csak akkor nézd meg, ha nagyon elakadtál, és sehogy nem tudod megoldani. De ne feledd amit innen másolsz, az nem számít bele a saját kontribúcióba.
 
Egy háromszög követésére egy lehetséges algoritmus:
(Ne feledd, amit innen másolsz, az nem számít bele a saját kontribúcióba.)


<br/> <syntaxhighlight lang="c">  
<br/> <syntaxhighlight lang="c">  
675. sor: 676. sor:


   // Az óra járásával ellentétes (CCW) körüljárási irányt feltételez ez a kód a pontok megadásakor.
   // Az óra járásával ellentétes (CCW) körüljárási irányt feltételez ez a kód a pontok megadásakor.
  // A köröljárási irányból döntjük el a normálvektor "előjelét".
   Triangle(const Vector& a, const Vector& b, const Vector& c)  
   Triangle(const Vector& a, const Vector& b, const Vector& c)  
     : a(a), b(b), c(c) {
     : a(a), b(b), c(c) {
695. sor: 697. sor:
     // ha az a sugár irányát vetítjük a normálvektorra, akkor meg
     // ha az a sugár irányát vetítjük a normálvektorra, akkor meg
     // megtudjuk, hogy az milyen gyorsan halad a sík fele.
     // megtudjuk, hogy az milyen gyorsan halad a sík fele.
     // Innen a már csak a t = s / v képletet kell csak használnunk.  
     // Innen a már csak a t = s / v képletet kell csak használnunk.
    // Megjegyzés: a nullával osztást nem kell külön esetként lekezelnünk.  
     float ray_travel_dist = dot(a - r.origin, normal) / dot(r.direction, normal);
     float ray_travel_dist = dot(a - r.origin, normal) / dot(r.direction, normal);


764. sor: 767. sor:
</syntaxhighlight> <br/>
</syntaxhighlight> <br/>
    
    
* A legközelebbi metszéspont kiszámolásához a legegyszerűbb (de leglassabb) megoldás, ha végigmegyünk az összes objektumon, és amikkel találtunk metszéspontot, azokra a metszéspontokra kiszámoljuk a kamerától vett távolságot, és ezeknek az értékeknek nézzük a minimumát.
A legközelebbi metszéspont kiszámolásához a legegyszerűbb (de leglassabb) megoldás, ha végigmegyünk az összes objektumon, és amikkel találtunk metszéspontot, azokra a metszéspontokra kiszámoljuk a kamerától vett távolságot, és ezeknek az értékeknek nézzük a minimumát. Ehhez persze el kell tárolni az összes objektumot egy helyre, hogy végig tudjuk iterálni rajtuk. De az objektumok különböző típusúak is lehetnek, itt sokat segít a heterogén kollekció használata. Az objektumok az én implementációmba azt is eltárolják, hogy milyen anyagból vannak.
** Ehhez persze el kell tárolni az összes objektumot egy helyre, hogy végig tudjuk iterálni rajtuk. De az objektumok persze különböző osztályúak is lehetnek, itt sokat segít a heterogén kollekció használata. Az objektumok az én implementációmba azt is eltárolják, hogy milyen anyagból vannak.


<br/> <syntaxhighlight lang="c">  
<br/> <syntaxhighlight lang="c">  
776. sor: 778. sor:
</syntaxhighlight> <br/>
</syntaxhighlight> <br/>


* És kell egy struktúra, ami tárolja ezeket, és végig tud menni rajtuk. Nem győzöm ismételni, hogy én csak egy lehetséges megoldást mutatok, hogy te ennél jobbat írhass, de semmiképpen se másold:
És kell egy struktúra, ami tárolja ezeket, és végig tud menni rajtuk. Az én megoldásom erre:


<br/> <syntaxhighlight lang="c">  
<br/> <syntaxhighlight lang="c">  
818. sor: 820. sor:
</syntaxhighlight> <br/>
</syntaxhighlight> <br/>


* Ha ennél gyorsabb algoritmusra van szükséged, akkor ajánlom egy BSP-fa implementálását, mármint konkrétan egy KD-fát csinálj, ne általános BSP-t. Ez nagyon gyors, és nem nehéz implementálni... csak meg kell írni...
Ha ennél gyorsabb algoritmusra van szükséged, akkor ajánlom egy BSP-fa implementálását, mármint konkrétan egy KD-fát csinálj, ne általános BSP-t. Ez nagyon gyors, és nem nehéz implementálni... csak meg kell írni...
* Ami a kódból is látszódik, hogy még nem vagyunk készen, amikor meghatároztuk a legközelebbi metszéspontot, ugyanis nekünk egy színre van szükségünk, amit megjeleníthetünk, nem egy helyvektorra.
 
Ami a kódból is látszódik, hogy még nem vagyunk készen, amikor meghatároztuk a legközelebbi metszéspontot, ugyanis nekünk egy színre van szükségünk, amit megjeleníthetünk, nem egy helyvektorra.


=== Megvilágítás ===  
=== Megvilágítás ===