Tworzenie gry w C# z użyciem silnika Ogre - cz.7
21.07.2011 - Mateusz Osowski
Program teksturującyDrugi fragment-program jaki napiszemy będzie potrafił teksturować siatki:
Jak widać, program konstrukcją przypomina poprzedni. Funkcja główna jednak zyskała drugi argument, jest nim zmienna oznaczona atrybutem uniform. Tego typu zmienne są pochodzenia zewnętrznego, tj. są przekazywane przez silnik. Do semantyki TEXUNIT0 przekazywana jest pierwsza użyta w przebiegu tekstura. Zwyczajne tekstury są w CG obsługiwane przez typ sampler2D . Ten program robi użytek z otrzymywanych współrzędnych mapowania tekstury - po prostu wydobywa odpowiedni teksel z tekstury za pomocą funkcji tex2D() .
Pierwszym argumentem funkcji tex2D() jest tekstura, z której odczytany ma być kolor, drugim zaś dwie współrzędne z przedziału [0,1].
Aby program zadziałał, musimy dostarczyć w przebiegu teksturę:
W bardzo łatwy sposób możemy dokonywać rozmaitych operacji na kolorach, np. zwiększyć kontrast tekstury dwukrotnie:
Vertex programDotychczas przetwarzaniem wierzchołków zajmował się fixed pipeline. Aby znalazły się one w naszej gestii, musimy użyć vertex programu:
Program cieniujący dla wierzchołków jest w istocie funkcją zwracającą pozycję wierzchołka w przestrzeni ekranu, zatem jego najprostszy wariant po prostu przepuszcza wejściową pozycję wierzchołka (jest to pozycja względem środka modelu) przez konkatenację macierzy świata (modelu), widoku i projekcji (przekształcenia modelu, kamery i rzutowanie na ekran). Ponieważ przejęliśmy kontrolę nad przetwarzaniem wierzchołków, musimy sami przekazywać dane potrzebne fragment-programowi, w tym przypadku współrzędne mapowania tekstury. Program wierzchołków rzadko kiedy jest bardziej rozbudowany. Często jednak warto przerzucić do niego kosztowne obliczenia z fragment-programu, jeżeli tylko jest taka możliwość. Większość zmiennych typu uniform przekazuje się poprzez pliki materiałów. W przypadku zmiennej WorldViewProj:
Silnik Ogre sam zadba o to, by przekazywać do zmiennej WorldViewProj aktualną macierz. Opis wszystkich zmiennych silnika dostępnych dla shaderów znajduje się pod adresem http://www.ogre3d.org/docs/manual/manual_23.html#SEC125. OświetleniePotrafimy już pisać programy cieniujące dla wierzchołków i fragmentów. Możemy więc rozpocząć implementację własnego oświetlenia. Na początku stworzymy bardzo proste shadery nieuwzględniające tekstur:Wejście i wyjście vertex-programu:
Do obliczenia oświetlenia potrzebujemy wektora normalnego. Dostarcza nam go Ogre pod semantykę NORMAL. Pozycję światła przekażemy jako zmienną uniform. Chcemy, aby pozycja światła była podana w przestrzeni obiektu (takiej, w której obiekt ma współrzędne (0,0,0)), by nie trzeba było przekształcać jej dodatkowymi macierzami. Do fragment-programu przesyłamy obliczony wektor kierunku światła (znormalizowany wektor kierunku od światła do wierzchołka), a także wektor normalny wierzchołka.
Podobnie jak w poprzednim vertex-programie, przekształcamy pozycję wierzchołka za pomocą macierzy. Następnie obliczamy wektor światła dla tego wierzchołka. Korzystamy z dostępnej wbudowanej funkcji normalize . Zmienna LightPosition jest oznaczona jako uniform, jej wartość uaktualniać będzie silnik. Dla świateł punktowych jest to (x,y,z,1), gdzie wartości (x,y,z) są współrzędnymi światła, zaś dla świateł kierunkowych (-x,-y,-z,0), gdzie (x,y,z) jest wektorem kierunku światła. Kierunek padania światła kierunkowego jest niezależny od pozycji wierzchołka, toteż w tym przypadku pomijamy pozycję wierzchołka zerując ją mnożąc przez LightPosition.w. Przejdźmy do fragment-programu.
Fragment-program jest prosty - oblicza natężenie oświetlenia fragmentu - iloczyn skalarany wektora normalnego i wektora światła. Musimy pamiętać, by przekazać dane światła do zmiennej uniform w plikach materiału. Zaaplikujmy programy cieniujące na postaci:
Liczba 0 przy zmiennej LightPosition oznacza numer światła. W tej prostej wersji obsługujemy tylko jedno światło, lecz gdy będziemy chcieli iterować po kilku światłach na przebieg, wtedy możemy pozycję każdego z nich zapisać do osobnej zmiennej. Indeks jest względny w zależności od parametrów iterowania. (1 ocena) |
Copyright © 2008-2010 Wrocławski Portal Informatyczny
design: rafalpolito.com