Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

courses:a4m39apg:raytracer_algoritmy [2009/11/26 02:37]
keymaster
courses:a4m39apg:raytracer_algoritmy [2025/01/03 18:29] (aktuální)
Řádek 1: Řádek 1:
 ====== Fragmenty kódu pro raytracer ====== ====== Fragmenty kódu pro raytracer ======
 +
 +**Disclaimer:​ nepoužívejte čemu nerozumíte,​ použití na vlastní nebezpečí,​ nemusí být správné, optimální,​ blablabla... ;)**
 +
 Z tohohle předmětu už je pomalu taky fraška, tak proč to dělat složitě... tady jsou hotový kusy kódu co se budou hodit. Vybral jsem to ze svojeho funkčního rendereru, takže by to mělo být korektní, ale za nic neručím ;). Nejasnosti a dotazy do diskuse prosím. Z tohohle předmětu už je pomalu taky fraška, tak proč to dělat složitě... tady jsou hotový kusy kódu co se budou hodit. Vybral jsem to ze svojeho funkčního rendereru, takže by to mělo být korektní, ale za nic neručím ;). Nejasnosti a dotazy do diskuse prosím.
   * Můj vektor se jmenuje Vector3d   * Můj vektor se jmenuje Vector3d
   * skalární a vektorový součin (dot & cross product) značím jako Vector3d::​dot a Vector3d::​cross   * skalární a vektorový součin (dot & cross product) značím jako Vector3d::​dot a Vector3d::​cross
 +  * předpokládám že jsme našli průsečík primárního paprsku s nejbližším objektem. Data o této intersekci jsou uložený ve struktuře hit 
 +  * integrator je objekt kterýmu dáte paprsek a on vám vrátí barvu
 +  * <​code>​__forceinline</​code>​ je MSVC klíčový slovo co zajistí inlinování funkce (odstraní se overhead z function callu a jede to rychlej). Něco jak "​inline",​ ale je to silnější.
  
 ==== Stínový paprsky ==== ==== Stínový paprsky ====
-sledují se stejně jako primární. Origin je hit location, target je světlo (nebo naopak). Nehledá se nejbližší průsečík,​ ale libovolný. Musí se ověřit že průsečík je mezi bodem a světlem, ne až za ním. **Je velmi vhodný posunout origin po směru paprsku o nějaký epsilon (0.001 nebo tak), protože jinak najde paprsek průsečík sám se sebou (self-intersection)**+sledují se podobně jako primární, ale nestínují se. Origin je hit location, target je světlo (nebo naopak). Nehledá se nejbližší průsečík,​ ale libovolný. Musí se ověřit že průsečík je mezi bodem a světlem, ne až za ním. **Je velmi vhodný posunout origin po směru paprsku o nějaký epsilon (0.001 nebo tak), protože jinak se paprsek protne s polygonem ze kterého byl vystřelen ​(self-intersection).**  
 + 
 +Pro toto se ve frameworku s uspechem vyuziji promenne tMin a tMax.
  
 ==== Ideální odraz ==== ==== Ideální odraz ====
-Vygenerujte paprsek, vystínujte jako primární (hlídat si hloubku zanoření, jinak 2 zrcadla proti sobě dají stack overflow). Opět to chce bias, aby se paprsek neprotl sám s tím samým povrchem v nulové vzdálenosti.+Vygenerujte paprsek, vystínujte jako primární (hlídat si hloubku zanoření, jinak 2 zrcadla proti sobě dají stack overflow). Opět to chce posunutí (bias), aby se paprsek neprotl sám s tím samým povrchem v nulové vzdálenosti.
  
 Směr paprsku je: Směr paprsku je:
 <code c++> <code c++>
-(ray.direction - hit.normal * 2 * Vector3D::​dot(ray.direction,​ hit.normal).normalize();​+( ray.direction - hit.normal * 2 * Vector3D::​dot(ray.direction,​ hit.normal).normalize();​
 </​code>​ </​code>​
  
Řádek 37: Řádek 45:
 </​code>​ </​code>​
  
-Ošetření toho když vám přijde refraktivní paprsek+Ošetření toho když vám přijde refraktivní paprsek: místo klasickýho stínování uděláte tohle:
 <code c++> <code c++>
 if(ray.type == RAY_REFRACTED){ if(ray.type == RAY_REFRACTED){
  //ray just travelled through material and hit surface again  //ray just travelled through material and hit surface again
  float IORratio = material.IOR;​  float IORratio = material.IOR;​
- float cos1 = Vector3d::​dot(context.normal, -ray.direction);​+ float cos1 = Vector3d::​dot(hit.normal, -ray.direction);​
  float cos2 = 1 - IORratio*IORratio*(1-cos1*cos1);​  float cos2 = 1 - IORratio*IORratio*(1-cos1*cos1);​
  Vector3d direction;  Vector3d direction;
  if(cos2 < 0){ //total internal reflection  if(cos2 < 0){ //total internal reflection
- direction = (ray.direction + 2*cos1*context.normal).normalize();​ + direction = (ray.direction + 2*cos1*hit.normal).normalize();​ 
- CoronaRay ​resurfaced(context.position+direction*Vector3d(SHADOW_BIAS),​ direction, RAY_REFRACTED,​ ray.depth );  + Ray resurfaced(hit.position+direction*Vector3d(SHADOW_BIAS),​ direction, RAY_REFRACTED,​ ray.depth );  
- return core->​integrator->​getColor(resurfaced, CoronaShadeContext(core));+ return core->​integrator->​getColor(resurfaced);​
  } else {  } else {
  cos2 = sqrt(cos2);  cos2 = sqrt(cos2);
  if(cos1 < 0)  if(cos1 < 0)
  cos2 = -cos2;  cos2 = -cos2;
- direction = (IORratio*ray.direction + (IORratio*cos1 - cos2)*context.normal).normalize();​ + direction = (IORratio*ray.direction + (IORratio*cos1 - cos2)*hit.normal).normalize();​ 
- CoronaRay ​resurfaced(context.position+direction*Vector3d(SHADOW_BIAS),​ direction, RAY_PRIMARY,​ ray.depth);​  + Ray resurfaced(hit.position+direction*Vector3d(SHADOW_BIAS),​ direction, RAY_PRIMARY,​ ray.depth);​  
- return core->​integrator->​getColor(resurfaced, CoronaShadeContext(core));+ return core->​integrator->​getColor(resurfaced);​
  }  }
 } }
Řádek 65: Řádek 73:
 GI paprsek: GI paprsek:
 <code c++> <code c++>
-VectorRotator rotator(context.normal);+VectorRotator rotator(hit.normal);
 RandomCouple x = random.getCosineLobeSample();​ RandomCouple x = random.getCosineLobeSample();​
 Vector3d direction = rotator.rotateVector(x);​ Vector3d direction = rotator.rotateVector(x);​
 </​code>​ </​code>​
  
-No, průser je ten random a vectorRotator. Random generuje vzorky s cosinovou hustotou. Vzorek je vektor na hemisféře okolo y osy. Vytvoří se takhle:+No, průser je ten random a vectorRotator. ​ 
 +Random generuje vzorky s cosinovou hustotou ​(viz. [[http://​www.cs.kuleuven.ac.be/​~phil/​GI/​TotalCompendium.pdf|Global Illumination Compendium]],​ str 19). Vzorek je vektor na hemisféře okolo y osy. Vytvoří se takhle:
  
 <code c++> <code c++>
Řádek 80: Řádek 89:
  
  
-VectorRotator rotuje vektory z hemisféry okolo y osy do hemisféry okolo hit normály. +VectorRotator rotuje vektory z hemisféry okolo y osy do hemisféry okolo hit normály. ​Je to vlastně ortonormální báze, kde y souřadnice je ve směru vaší normály. Tahle báze se vyrobí takhle:
-Inicializuje ​se takto:+
 <code c++> <code c++>
 __forceinline VectorRotator(const Vector3d&​ normal){ __forceinline VectorRotator(const Vector3d&​ normal){
Řádek 89: Řádek 97:
  Vector3d temp = normal;  Vector3d temp = normal;
  
- if(fabs(temp.x) < fabs(temp.y)) {+ if(fabs(temp.x) < fabs(temp.y)) {     
 + //tahle šaškárna je o tom že potřebuju vyrobit jakejkoliv vektor kterej bude zaručeně nerovnoběžnej s normálou
  temp.x = 2;  temp.x = 2;
  } else {  } else {
Řádek 131: Řádek 140:
 </​code>​ </​code>​
 Možná to není úplně to co oni chcou, nemachruju tam s tou BRDF funkcí, ale je to rychlý a kompaktní, tak snad se nehraje na city ;) Možná to není úplně to co oni chcou, nemachruju tam s tou BRDF funkcí, ale je to rychlý a kompaktní, tak snad se nehraje na city ;)
 +
 +--- Nejsem si jistý, ale tohle podle mě je BRDF, ne?  --- //​[[[email protected]|Roman Polášek]] 2009/12/04 18:01//
  
 ==== Area Lights ==== ==== Area Lights ====
-Je potřeba zvolit pokaždý jinej náhodnej sample na světle a udělat na něj klasickej shadowray. IMplementovaný zatím mám jen triangle světla. Docela lahůdka je ale s intenzitama,​ sám v tom mám bordel, možná je tam chyba:+Je potřeba zvolit pokaždý jinej náhodnej sample na světle a udělat na něj klasickej shadowray. IMplementovaný zatím mám jen triangle světla. Docela lahůdka je ale s intenzitama,​ sám v tom mám bordel, možná je tam chyba
 + 
 +Možná budete chtít si ten kód upravit pro ty obdélníkový světla, mohlo by to taky být docela podezřelý. Úprava spočívá pouze ve změně generováním randomPoint na nějaký triviální point + random1*direction1 ​ + random2*direction2 
 <code c++> <code c++>
-RgbColor __forceinline getIrradianceSecondary(const ​CoronaShadeContextcontext,+RgbColor __forceinline getIrradianceSecondary(const ​Hithit,
  Abstract::​AccelerationStructure* structure){  Abstract::​AccelerationStructure* structure){
  RandomCouple randomCouple(global->​random->​uniformCouple());​  RandomCouple randomCouple(global->​random->​uniformCouple());​
Řádek 146: Řádek 160:
  
  
- Vector3d direction = randomPoint - context.position;​ + Vector3d direction = randomPoint - hit.position;​ 
- CoronaRay ​shadowRay(context.position, direction.normalize());​+ Ray shadowRay(hit.position, direction.normalize());​
  
- float cosineSurface = Vector3d::​dot(context.normal, shadowRay.direction);​+ float cosineSurface = Vector3d::​dot(hit.normal, shadowRay.direction);​
  if(cosineSurface < TRESHOLD)  if(cosineSurface < TRESHOLD)
  return RgbColor();  return RgbColor();
Řádek 157: Řádek 171:
  
  float distance = direction.x/​shadowRay.direction.x;​  float distance = direction.x/​shadowRay.direction.x;​
- shadowRay.origin = context.position + SHADOW_BIAS*shadowRay.direction;​+ shadowRay.origin = hit.position + SHADOW_BIAS*shadowRay.direction;​
  
  if(scene->​castsShadow(shadowRay,​ distance - (2*SHADOW_BIAS)))  if(scene->​castsShadow(shadowRay,​ distance - (2*SHADOW_BIAS)))
Řádek 163: Řádek 177:
  
  //druhá důležitá věc: násobí se dvěma cosiny. Koukněte do shirleyho kdyžtak  //druhá důležitá věc: násobí se dvěma cosiny. Koukněte do shirleyho kdyžtak
- //jo a tohle světlo má kvadratickej ​útlum ​(dělení distance*distance  + //jo a je tam útlum ​podle těch 3 koeficientů viz zadání 
- return this->​color * cosineSurface * cosineLight / (distance*distance);​+ return this->​color * cosineSurface * cosineLight / (distance*distance ​* quadraticAtten + distance * linearAtten + constantAtten);
 } }
 </​code>​ </​code>​
courses/a4m39apg/raytracer_algoritmy.1259199466.txt.gz · Poslední úprava: 2025/01/03 18:25 (upraveno mimo DokuWiki)
Nahoru
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0