Distribuovaný Raytracing

Distribuovaný raytracing je fotorealistický 3D vykresľovací algoritmus, ktorý využíva integrovanie metódou Monte Carlo na výpočet intenzity svetla, ktoré dopadá na jednotlivé body na povrchu objektov scény. Algoritmus jednotlivo simuluje tok svetla na scéne, ktoré sa pohybujú smerom od svetla do kamery. Vychádza z algoritmu raytracing.

S raytracingom prichádzajú možnosti pridávať rôzne efekty ako je napr. aj hĺbka ostrosti

"Bežný" raytracing upraviť

V bežnom raytracing-u sa pri každom dopade na objekt sa vygeneruje len jeden lúč v smere k svetlu. V závislosti od uhla, pod akým svetlo dopadá a jeho materiál, potom algoritmus vypočíta, ako bude konkrétny bod osvetlený. Keďže je lúč len 1, z miesta x vieme určiť len či je osvetlený alebo nie, vylučujeme prípad, keď je napríklad svetelný zdroj plocha a miesto je čiastočne zatienené iným objektom, alebo keď svetlo dopadá na bod x nepriamo, po odraze od nejakej inej plochy. Bežný raytracing s nepriamym osvetlením počíta, ale len s jeho zrkadlovou zložkou.

Distribuovaný raytracing upraviť

Modifikácia spočíva v tom, že z každého miesta vygeneruje do celej hemisféry N lúčov (pre pevne dané N), z ktorých vypočíta príspevky priameho aj nepriameho osvetlenia. To prinesie niekoľko efektov ako napríklad mäkké tiene alebo mäkké odrazy. Príspevok z nepriameho osvetlenia algoritmus spočíta tak, že z daného miesta vygeneruje znovu N nových rôznych lúčov rovnakou metódou. Z toho plynie vysoká časová zložitosť, ktorá bude v tomto prípade exponenciálna v závislosti na hĺbke rekurzie. Tento problém rieši algoritmus path Tracing, ktorý generuje lúč zakaždým len 1 s rôznou pravdepodobnosťou.

Popis algoritmu upraviť

  1. Na začiatku nech x je pozícia kamery
  2. Zvoľ si smer ω cez pixel na obrazovke smerom od kamery do scény
  3. Nájdi priesečník y smeru ω so scénou
Ak je y súčasť svetla, vráť sa a pripočítaj príspevok
Ak y neexistuje, vráť sa a pripočítaj farbu okolia
Ak y je bod na scéne s nejakou odrazivosťou, zvoľ x ako kameru a vygeneruj N nových smerov ω1 až ωN a pokračuj v bode 3. Potom sa vráť, zo všetkých príspevkov vypočítaj ich vážený priemer a ten vynásob funkciou odrazivosti.

Pseudokód upraviť

function renderImage() 
{
   for all pixels
   {
      Color pixelCol = (0,0,0);
      for k = 1 to N
      {
         wk := náhodný smer cez k- pixel
         pixelCol += getLi(camPos,wk)
      }
      return Lo / N
   }
}
getLi(x, w)
{
   hit := NearestIntersect(x, wi)
   wo  := -wi;
   y   := hit.pos;
   if no intersection
      return backgroundCol;
   else
   {
      Lo = (0,0,0)
      for k = 1 to N
      {
         wk := náhodný smer na hemisfére s hustotou p(w)
         Lo += getLi(y, wk) * fr(y, wk, wo) * dot(hit.n,wk) / pdf(wk)
      }
      return Lo / N + directLighting (y, wo);
   }
}