poniedziałek, 13 kwietnia 2009

Odroczone oświetlenie

Jakoś dawno nic nie napisałem. Nie było o czym i kiedy. Święta skończą się dla mnie jutro. Jak dobrze pójdzie to w środę wrócę do mojej pracy mgr inż.

Ponieważ oświetlenie zaczęło działać postanowiłem je popsuć :) Konkretniej to nadszedł czas aby zamienić klasyczne podejście na cieniowanie odroczone. Przez te dwa tygodnie przemyślałem sprawę, poczytałem co nieco, odkryłem kilka problemów, generalnie poważnie zbliżyłem się do zaimplementowania tej metody.

Jednym z problemów jest to jakiej geometrii użyć przy renderowaniu świateł. Pomysłów miałem kilka.
1) Pełno ekranowy quad. Za długo się nad tym nie zastanawiałem. Uruchomienie 200 razy shadera dla każdego piksela jest pomysłem złym.
2) Modyfikacja punktu 1, polegająca na przycięciu quad'a do rozmiarów ekranowych światła. Pytanie tylko jak to zrobić.
a) Wojciech Toman w swoim artykule proponuje zastosowanie metody opisanej tutaj. Mi się ona jednak nie podoba.
b) Wykorzystujemy macierz świata z odpowiednio zmodyfikowanymi współczynnikami skali i translacji. Wykonujemy normalną transformację i quad pokrywa cała niezbędną powierzchnię. Tylko, że w ten sposób renderujemy więcej pikseli niż jest to konieczne. Światło jest kuliste, a quad jest prostokątny, czyli na oko (4 - Pi) * r^2 pikseli za dużo. Poza tym musimy renderować taki quad z wyłączonym testem Z (przynajmniej ja do takiego wniosku doszedłem).
3) Kula. Z całą pewnością da dużo lepsze przybliżenie kształtu światła na ekranie. Można też wykorzystać Z test. Tylko, że geometria robi się skomplikowana. Może się okazać, że więcej stracimy na transformacji niż zyskamy na precyzji.
4) Sześcian. Pewien kompromis pomiędzy 2b i 3.
KulaQuad
Przybliżenie-+
Geometria+-
Z test=+
Mamy więc 3 +, 2 - i 1 remis. Dlatego wybrałem właśnie sześcian jako geometrię dla światła.

O co chodzi z tym Z test'em. Wymyśliłem (pewnie nie ja pierwszy), że można wykorzystać go do eliminacji pikseli tła podczas rysowania pierwszoplanowych świateł. Cała sztuczka polega na rysowaniu światła za geometrią z ustawionym testem Z na funkcję "greater". Potrzebujemy do tego bryły, która obejmuje całą niezbędną przestrzeń.
1) Macierz świata musi dokonać skalowania i translacji. Rotacja nie jest konieczna.
2) Zmieniamy funkcję Z.
3) Wyłączamy zapis Z.
4) Zmieniamy culling na rysowanie backface'ów.
5) Renderujemy sześcian.

Podczas kodowania wymyśliłem, że odwrócenie funkcji Z i cullingu pozwoli na eliminację w odwrotnej sytuacji, czyli pikseli pierwszoplanowych dla świateł w oddali.

1 komentarz:

lednar pisze...

Ciekawy artykuł.