„Számítógépes grafika házi feladat tutorial” változatai közötti eltérés
| 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. 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: | |||
<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. | |||
** 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á. | ||
* Nagyon sok esetben az okoskodás, pl transzformációk használata ''nagyon'' le tud egyszerűsíteni egy ilyen problémát. | |||
* 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. | |||
* Á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é. | |||
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. 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. | |||
<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. 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... | |||
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 === | ||