środa, 29 kwietnia 2009

GUI

Nie dawno uznałem, że nadszedł moment od którego scena powinna być ładowana z pliku. Co oznacza konieczność utworzenia jakiegoś formatu sceny, importera i co najgorsze edytora. Jakoś nie mam ochoty ręcznie zapisywać liczb typu float.

Jak tu napisać edytor ? Poza win API i javą nie znam, żadnego narzędzia do robienia GUI. Edytor potrzebuje jakoś ładować, zapisywać i wyświetlać taką scenę. Pisanie wszystkiego dwa razy to absurd, więc java odpada. Pisanie edytora w win API też mi się nie uśmiecha. Wpadłem na idiotyczny pomysł, napiszę sobie GUI w oparciu o mój silnik. Sam się zastanawiam, po co ja to robię ?! Istnieją już gotowe biblioteki, choćby Cegui. Na razie walczę, jak uznam swą porażkę z czasem, to pomyślę nad gotowcem:

niedziela, 19 kwietnia 2009

Odroczone oświetlenie 2

Drugi post od kiedy nad tym pracuję.

Natknąłem się na dziwny problem z CG. Przyznam, że nie wiem czy to moja wina czy biblioteki. Nagle CG przestało lubić shader nad którym pracowałem. Cały problem jest opisany tutaj. Z jednej strony sam nie mogę uwierzyć, że trafiłem na bug'a. Ta biblioteka powinna być naprawdę dobrze przetestowana. Z drugiej strony mój kod działał poprawnie przez pół roku i nagle przestał ?! Nie, nie tak to nie ma :)

Czemu uważam, że mój kod jest w porządku:
1) Poprawnie ładowane są wszystkie pozostałe shadery, w tym kilka równie "skomplikowanych" co ten felerny.
2) Kod działał poprawnie od dawna. Nie robiłem żadnych specjalnych testów, ale przeszedł chrzest bojowy.
3) Każde wywołanie funkcji z cg ma walidowany wynik.
4) Zwrócony błąd według CG to: Unkown error, dla DX to Invalid data.

Jak będę miał trochę wolnego czasu, to może wrócę do cg i poszukam rozwiązania. Póki co przeniosłem kod odpowiedzialny za shadery całkowicie na directx:

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.