| Description | Hierarchy | Fields | Methods | Properties |
type TRayTracer = class(TObject)
![]() |
Octree: TVRMLBaseTrianglesOctree; |
![]() |
Image: TImage; |
![]() |
CamPosition: TVector3_Single; |
![]() |
CamDirection: TVector3_Single; |
![]() |
CamUp: TVector3_Single; |
![]() |
ViewAngleDegX: Single; |
![]() |
ViewAngleDegY: Single; |
![]() |
SceneBGColor: TVector3_Single; |
![]() |
PixelsMadeNotifier: TPixelsMadeNotifierFunc; |
![]() |
PixelsMadeNotifierData: Pointer; |
![]() |
FirstPixel: Cardinal; |
![]() |
procedure Execute; virtual; abstract; |
![]() |
Octree: TVRMLBaseTrianglesOctree; |
|
This describes the actual scene that will be used. Must be set before calling Execute. | |
![]() |
Image: TImage; |
|
Image where the ray-tracer result will be stored. Must be set before calling Execute. We will not resize given here Image. Instead we will use it's current size — so you just have to set Image size as appropriate before calling this method. We will write on image using TImage.SetColorRGB method, so this method must be implemented in Image class you use (it's implemented in all 3 classes TRGBImage, TRGBAlphaImage, TRGBEImage in Images unit, so usually you just don't worry about that). Dla kazdego pixela w ktorym promien trafia na obiekt ze sceny zapisujemy w obrazku wyliczony kolor RGB sceny w tym miejscu. Nie dotykamy kanalu Alpha obrazka TRGBAlphaImage. (kiedys mialem tu mechanizm obslugi tego kanalu ale zbytnio mi zawadzal a i tak nie byl uzywany, dlatego go wylaczylem). Akceptujemy naturalnie obrazki TRGBEImage i bedziemy w nich zapisywali precyzyjne kolory — de facto format TRGBEImage zaimplementowalem wlasnie po to zeby raytracery w tym module mogly zapisywac obrazki precyzyjnie, z kolorami jako 3xFloat. Ponadto, gdy uzywasz dowolnego formatu innego niz TRGBEImage (patrzac przyszlosciowo : dowolnego formatu z precyzja i zakresem float) tracisz nie tylko precyzje : kolory 3xSingle sa konwertowane na 3xByte a konwersja Byte->Single jest robiona tak jak VectorMath.Vector3Byte : zakres Single 0-1 jest skalowany na zakres bajtu 0-255, jezeli wartosc Single jest wieksza niz 1 (co jest przeciez zupelnie mozliwe) to jest obcinana do 1. Wiec zapisujac do ikRGB/ikAlpha moze sie okazac ze przy bardzo jasnej scenie wyjdzie ci caly bialy obrazek - podczas gdy przy ikRGBE obrazek mialby po prostu kolory wieksze niz (1.0, 1.0, 1.0) co moznaby zawsze zniwelowac skalowaniem albo korekcja gamma. Ta zaleta formatu RGBE jest pokrotce opisana takze na poczatku dokumentacji do rayhuntera na [http://vrmlengine.sourceforge.net/rayhunter.php]. (Ta wada formatow RGB/Alpha nie bedzie naprawiona w tej funkcji bo niby jak ? Jedynym sensownym rozwiazaniem jest tutaj zapisac obrazek raytracerem w formacie RGBE a potem, po wygenerowaniu calosci, ustalic maksymalna wartosc komponentu i zrobic odpowiednie skalowanie lub korekcje gamma; ale do tego nie musze wcale naprawiac tej funkcji — wiec mozna co najwyzej uznac to za blad rayhuntera i view3dscene ze takiego naprawiania nie robia po uzyciu RaytraceTo1st. Ale: view3dscene zrzuca sprawe na "view3dscene nigdy nie mial realizowac raytracingu do celu innego niz tylko testowanie, tzn. view3dscene nie sluzy do generowania ostatecznych dopieszczonych obrazkow - od tego jest rayhunter". A rayhunter argumentuje ze "zeby to zrobic to w srodku rayhuntera musialbym robic zapis do RGBE i dopiero na koncu konwertowac do RGB : w ten sposob nie tylko komplikuje sobie kod ale takze robienie --write-partial-row staje sie klopotliwe. A wiec, na podobnej zasadzie jak funkcja Execute zwala problem na kod zewnetrzny, tak rayhunter zwala problem na program zewnetrzny. Innymi slowy, zawsze generuj obrazki do RGBE jesli nie chcesz miec tego problemu. Zreszta, Radiance tez tak robi : zawsze zapisuje obrazki do swojego RGBE i potem w czasie post-processingu obrazka umozliwia robienie korekcji kolorow)" ) Wszystkie pixle obrazka zostana zapisane przez raytracer. Kiedys mialem tu mechanizm umozliwiajacy podlozenie pod rendering tla, ale skasowalem to bo bylo malo uzyteczne a bardzo nieeleganckie w zapisie (wymagalo ode mnie rozrozniania czy promien pierw. trafil w scene czy nie; teraz po prostu promien ktory nie trafia w scene przynosi kolor SceneBGColor). | |
![]() |
CamPosition: TVector3_Single; |
|
Parametry | |
![]() |
CamDirection: TVector3_Single; |
|
Parametry CamPosition, | |
![]() |
CamUp: TVector3_Single; |
|
Parametry CamPosition, CamDirection, | |
![]() |
ViewAngleDegX: Single; |
|
| |
![]() |
ViewAngleDegY: Single; |
|
ViewAngleDegX i | |
![]() |
SceneBGColor: TVector3_Single; |
![]() |
PixelsMadeNotifier: TPixelsMadeNotifierFunc; |
|
Na pytanie KTORE konkretnie pixele zostaly zrobione, tzn. gdzie na obrazku jest to PixelsDoneCount pixli, inaczej mowiac : w jakiej kolejnosci robimy pixle : dla ClassicRayTracera: jak TSwapScanCurve dla PathTracera: zalezy od SFCurveClass; Wszystko przez to ze SFCurveClass okazaly sie praktycznie bezuzyteczne dla path tracera, niczego tam nie przyspieszaja. Ale byc moze okaza sie bardziej laskawe dla Classic RayTracera. Na razie nie zaimplementowalem jeszcze w ClassicRayTracerze shadow-cache a wiec takze te SFCurveClass sa bez sensu, ale kiedys planuje to zrobic. Chwilowo powinienes zawsze uzywac w path tracerze BestRaytrSFC aby miec TSwapScanCurve ktore renderuje prosto wierszami. Wiekszych komplikacji nie ma sensu na razie gdziekolwiek wprowadzac skoro uzywanie innych SFC niz renderujace wierszami od dolu do gory jest bezcelowe (dla path tracera) lub niezaimplementowane (dla classic ray tracera). Remember that pixels not done yet have the same content as they had when you Execute method started. In other words, if you set | |
![]() |
PixelsMadeNotifierData: Pointer; |
![]() |
procedure Execute; virtual; abstract; |
|
Do ray-tracing: write a ray-traced image into the Image. | |