Class TPathTracer

DescriptionHierarchyFieldsMethodsProperties

Unit

Declaration

type TPathTracer = class(TRayTracer)

Description

Path tracer. See [http://vrmlengine.sourceforge.net/vrml_engine_doc/output/xsl/html/ch04s03.html] for documentation.

Hierarchy

Overview

Fields

Public MinDepth: Integer;
Public RRoulContinue: Single;
Public PrimarySamplesCount: Cardinal;
Public NonPrimarySamplesCount: Cardinal;
Public DirectIllumSamplesCount: Cardinal;
Public SFCurveClass: TSpaceFillingCurveClass;

Methods

Public constructor Create;
Public procedure Execute; override;

Description

Fields

Public MinDepth: Integer;

MinDepth i RRoulContinue razem ustalaja warunki konczenia sciezki. Wyglada to tak ze do glebokosci rekursji MinDepth wchodzimy na pewno, natomiast glebiej wchodzimy pod warunkiem powodzenia w rosyjskiej ruletce, tzn. jezeli Depth <= 0 to musi byc Random < RRoulContinue i wtedy wywolujemy Trace(...,Depth-1) i wynik skalujemy przez 1/RRoulContinue.

Jezeli nie chcesz uzywac w ogole rosyjskiej ruletki to daj RRoulContinue = 0.0 (tak, porownywanie Random < RRoulContinue jak zwykle uzywa _ostrej_ nierownosci, co jest konsekwente bo Random zwraca wyniki z przedzialu [0;1) ). Przestrzegam jednak przed rezygnowaniem z rosyjskiej ruletki - rezygnacja ta powoduje bias na obrazku; obrazek wynikowy jest ciemniejszy niż powinien być. Przestrzegam też przed dawaniem _bardzo_ malych wartosci dla RRoulContinue - w wyniku tego bedziemy niekiedy skalowali wynik przez 1/RRoulContinue (= bardzo duzo jezeli RRoulContinue = bardzo malo) a niekiedy wynik bedzie = 0, wiec rosyjska ruletka spowoduje tu olbrzymia wariancje (a wiec noise). RRoulContinue powinno byc w zakresie 0..1, jesli nie jest - bedzie clamped.

Jezeli nie chcesz uzywac MinDepth (to znaczy chcesz zeby o kazdym wywolaniu rekurencyjnym decydowala rosyjska ruletka) to przekaz MinDepth = 0. (wartosci MinDepth < 0 w tej chwili sa w zasadzie dopuszczalne i traktowane przez implementacje tak samo jak MinDepth = 0 ale byc moze kiedys sie to zmieni).

Uzywanie rosyjskiej ruletki gwarantuje nam ze nie mamy biasu (bez wzgledu na MinDepth). Uzywanie MinDepth zmniejsza wariancje (chociaz naturalnie wydluza czas dzialania bo przeciez sciezki beda mialy zawsze jakas minimalna dlugosc, no, za wyjatkiem tych nielicznych sciezek ktore urwa sie w sposob "naturalny", tzn. wyleca na zewnatrz sceny itp.). Razem, uzywanie MinDepth w polaczeniu z rosyjska ruletka daje wynik unbiased i czesciowo niweluje noise powodowany przez rosyjska ruletke.

Public RRoulContinue: Single;
 
Public PrimarySamplesCount: Cardinal;

Primary- i NonPrimary- SamplesCount okreslaja ile sciezek wygenerowac dla kazdego pixela (obie musza byc >0, co jest sprawdzane uzywajac Check(), nawet w wersji RELEASE). Primary mowi ile promieni pierwotnych jest puszczanych dla kazdego pixela obrazka; dla kazdego promienia pierwotnego ktory trafi w scene generowanych jest nastepnie NonPrimary sciezek (tzn. teraz juz prawdziwych sciezek, ktore nie rozgaleziaja sie dalej). Razem mamy wiec Primary*NonPrimary sciezek dla kazdego pixla. Jezeli dasz NonPrimary = 1 i bedziesz operowal tylko Primary to w rezultacie otrzymasz naiwna wersje path tracera, ktora np. dla 1000 sciezek bedzie musiala przesledzic 1000 (tyle samo) promieni. O ile wziecie 1000 sciezek ma sens jesli chcesz miec ladny obrazek z path tracera o tyle liczenie az 1000 promieni pierwotnych ma tutaj male zastosowanie. Wiekszosc z tych promieni pierwotnych bedzie trafiala w jeden i ten sam punkt sceny i dopiero dalsze kroki sciezki beda determinowaly faktyczne roznice w kolorach przynoszonych przez konkretne sciezki. Innymi slowy, promienie pierwotne tworza scisla wiazke i chcemy to wykorzystac. W powyzszym przykladzie zmiana na Primary = 1 i NonPrimary = 1000 da ciagle 1000 sciezek na scene (i rendering rzeczywiscie bedzie mial taka sama jakosc, taki sam poziom szumu) a czas renderowania bedzie mniejszy (o ile dokladnie bedzie krotszy - to zalezy od dlugosci sredniej sciezki, jesli sciezki sa b. dlugie to niewiele tutaj pomozemy bo w koncu optymalizujemy tylko 1 krok kazdej sciezki; ale zazwyczaj sciezki nie sa zbyt dlugie). Jedyna wada to ze zmniejszenie Primary do 1 spowodowalo aliasing. Mozna temu zaradzic zwiekszajac (ale tylko nieznacznie !) Primary, np. Primary = 10 i NonPrimary = 100 powinno dac nam dobry antialiasing, zachowujac 1000 sciezek dla pixela i jednoczesnie lepszy czas renderowania. Faktem ktory ratuje nam tutaj tylek jest to ze dla antialiasingu nie potrzebujemy az tak wielu probek na pixel.

Public NonPrimarySamplesCount: Cardinal;

Primary- i NonPrimary- SamplesCount okreslaja ile sciezek wygenerowac dla kazdego pixela (obie musza byc >0, co jest sprawdzane uzywajac Check(), nawet w wersji RELEASE). Primary mowi ile promieni pierwotnych jest puszczanych dla kazdego pixela obrazka; dla kazdego promienia pierwotnego ktory trafi w scene generowanych jest nastepnie NonPrimary sciezek (tzn. teraz juz prawdziwych sciezek, ktore nie rozgaleziaja sie dalej). Razem mamy wiec Primary*NonPrimary sciezek dla kazdego pixla. Jezeli dasz NonPrimary = 1 i bedziesz operowal tylko Primary to w rezultacie otrzymasz naiwna wersje path tracera, ktora np. dla 1000 sciezek bedzie musiala przesledzic 1000 (tyle samo) promieni. O ile wziecie 1000 sciezek ma sens jesli chcesz miec ladny obrazek z path tracera o tyle liczenie az 1000 promieni pierwotnych ma tutaj male zastosowanie. Wiekszosc z tych promieni pierwotnych bedzie trafiala w jeden i ten sam punkt sceny i dopiero dalsze kroki sciezki beda determinowaly faktyczne roznice w kolorach przynoszonych przez konkretne sciezki. Innymi slowy, promienie pierwotne tworza scisla wiazke i chcemy to wykorzystac. W powyzszym przykladzie zmiana na Primary = 1 i NonPrimary = 1000 da ciagle 1000 sciezek na scene (i rendering rzeczywiscie bedzie mial taka sama jakosc, taki sam poziom szumu) a czas renderowania bedzie mniejszy (o ile dokladnie bedzie krotszy - to zalezy od dlugosci sredniej sciezki, jesli sciezki sa b. dlugie to niewiele tutaj pomozemy bo w koncu optymalizujemy tylko 1 krok kazdej sciezki; ale zazwyczaj sciezki nie sa zbyt dlugie). Jedyna wada to ze zmniejszenie Primary do 1 spowodowalo aliasing. Mozna temu zaradzic zwiekszajac (ale tylko nieznacznie !) Primary, np. Primary = 10 i NonPrimary = 100 powinno dac nam dobry antialiasing, zachowujac 1000 sciezek dla pixela i jednoczesnie lepszy czas renderowania. Faktem ktory ratuje nam tutaj tylek jest to ze dla antialiasingu nie potrzebujemy az tak wielu probek na pixel.

Public DirectIllumSamplesCount: Cardinal;

DirectIllumSamplesCount okresla ile sampli ma byc wyslanych zeby w kazdym punkcie sciezki obliczyc bezposrednio direct illumination (tzn. kazdy taki sample jest skierowany w strone losowego punktu losowego zrodla swiatla). Podaj tutaj 0 aby miec "naiwny path tracing" : liczy direct i indirect illumination probujac wygenerowac sciezki ktore trafilyby w zrodlo swiatla. Potrzebuje naprawde olbrzymiej ilosci [Non]PrimarySamplesCount zeby dac jakiekolwiek rezultaty. Podaj tutaj 1 lub wiecej aby miec typowego path tracera. Dla wartosci rownej 1 rezultaty sa juz dobre.

Public SFCurveClass: TSpaceFillingCurveClass;

For now it's not useful to change the value of this field. Using any other than default (TSwapScanCurve) curves doesn't give any speed benefit.

TSwapScanCurve przynajmniej pozwala latwo oddzielic na obrazku czesc zrobiona i niezrobiona (i dzieki temu np. view3dscene moze szybciej rysowac obrazek w miare generowania).

Methods

Public constructor Create;
 
Public procedure Execute; override;
 

Generated by PasDoc 0.11.0 on 2008-09-12 11:58:45