2011-10-26

Zmiany wymuszone przez pojawienie się refrakcji

Po pierwsze promień stał się obiektem immutable. Pojawiła się w nim jedna nowa właściwość mówiąca czy jest promieniem odbitym czy załamanym.

Informacja ta jest wykorzystywana przez przez dwie właściwości RefractedSideObject i ReflectedSideObject, których kod gettera korzysta z tej właściwości promienia by wyznaczyć w jaki obiekt wchodzi promień i z jakiego wychodzi. Te zaś służą do wyznaczenia współczynnika pochłaniania światła jak i refrakcji.

Wraz z tym musiała się pojawić nowa funkcja FindOuterObject do wyznaczania obiektu zewnętrznego poprzez wypuszczenie promienia. Jest ona także używana do prekalkulowania tłumienia ośrodka w jakim znajduję się źródło światła.

Kolejna dużą rzeczy może nie tyle wymuszoną ale dodaną dla większej realności są półprzeźroczyste cienie. Czyli chodzi nie tyle o zbadanie czy stoi coś na drodze do światła od punktu uderzenia, ale o sprawdzenie czy to coś jest przeźroczyste. Tak długo jak jest cień rzucany przez to źródło światła to nie absolutna czerń. Do jego kalkulacji wykorzystujemy współczynnik pochłaniania refrakcji, który mówi nam jaki procent energii przechodzi przez powierzchnie podczas refrakcji oraz jaki jest współczynnik pochłania światła w danym obiekcie.

Oczywiście przy braku globalnej iluminacji cienie takie są sztuczne - nie są załamane. Ale i tak wygląda to lepiej niż cienie solidne.

No i dodać należało wspomniane wyżej współczynniki pochłaniania energii podczas refrakcji i refleksji. Pochłanianie to nie zależy od drogi promienia. Poza tym w przeciwieństwie do współczynnika pochłaniania jest to warstwa materiału. Można ją np. wykorzystać do symulacji cienkiego foliowego nadruku. Współczynnik pochłaniania jest dany dla materiału i dla obiektu obowiązuje w całej jego objętości w jego wnętrzu.

Każdy materiał od teraz ma współczynnik refrakcji. Jest on dany liczbą. Nie jest warstwą materiału. Trudno sobie wyobrazić jak by to miało działać. Dodatkowo każdy obiekt ma właściwość czy jest domknięty, tylko obiekty domknięte mogą mieć współczynniki refrakcji.

W FindOuterObject musiałem zrezygnować z kodu na pominięcie detekcji obiektu samego ze sobą, by obsłużyć przypadki r>R dla torusa.

Po dodaniu refrakcji poprzednia procedura intersekcji sfery z promieniem okazała się zawodna. Jeśli poprzednie uderzenie nastąpiło w sferę informacja o tym, z której strony nastąpiło uderzenie już nam nie wystarczy do tego by stwierdzić czy uderzenie w ogóle nastąpi. Np. promień uderza z zewnątrz. Ponowna intersekcja jeśli myślimy tylko o promieniu odbitym nie ma sensu. Ale sprawy się mają bardziej skomplikowanie kiedy dochodzi nam promień załamany.

Najważniejszy jest początkowy fragment kodu:
if ((a_source_ray_intersection != null) && 
    a_source_ray_intersection.SceneObject == this)
{
    Debug.Assert((a_ray.RaySurfaceSide == RaySurfaceSide.RefractedSide) ||
                 (a_ray.RaySurfaceSide == RaySurfaceSide.ReflectedSide));
    if (a_source_ray_intersection.BackHit ^ 
       (a_ray.RaySurfaceSide == RaySurfaceSide.ReflectedSide))
    {
        return Scene.NoIntersection;
    }
    else

Od teraz promień niesie z sobą informację, czy jest promieniem odbitym, załamanym albo jakimś innym (np. od kamery). Ta dodatkowa informacja nie pojawiła się tylko by uzupełnić kod sfery. Równie dobrze tych warunków mogłoby nie być. Intersekcję możemy za każdym razem liczyć. Ale niejako wraz z pojawieniem się refrakcji, kod sfery przestał działać, a dodatkowa informacja w promieniu, która pozwala kodowi sfery dalej działać jest wymagana ogólnie do działania refrakcji.

Brak komentarzy:

Prześlij komentarz