Obejrzyj pliki shader_4_1.vert i shader_4_1.frag. Zwróć uwagę w szczególności na zmienną interpNormal
, przy uzyciu ktorej wektory normalne są przesyłane z vertex shaderze do fragment shadera. Pliki shader_4_2.vert i shader_4_2.frag na razie nie będą wykorzystywane
diffuse
):Prześlij do fragment shadera zmienna typu uniform vec3
(nazwij ją np. lightDir
), w której będzie się znajdować wektor kierunkowy:
Należy to zrobić podobnie do tego, jak przesyłana jest zmienna objectColor
. Jedyna różnica będzie taka, ze kierunek padania światła nie zależy od obiektu, wiec wywołanie glUniform3f
powinno pojawić się tylko raz, przed rysowaniem wszystkich obiektów.Wywołaj glUseProgram(program)
przed przesłaniem zmiennej.
Jako kierunek światła wybierz dowolny wektor jednostkowy. (Możesz wziąć dowolny niezerowy wektor następnie go znormalizować)
znormalizuj wektor normalny przed użyciem go w obliczeniach (uśrednianie wektorów normalnych wierzchołków może spowodować, ze przestaje one być jednostkowe).
Natężenie to iloczyn skalarny wektora normalnego powierzchni i odwrotnego wektora kierunku padania światła. Skorzystaj z funkcji dot
.
Natężenie nie może być ujemne. Przytnij natężenie do zera przy użyciu: x = max(x, 0.0)
(Wektory normalne są w układzie lokalnym modelu, a wektor padania światła w układzie świata)
Należy wykonać transformacje wektorów normalnych do przestrzeni świata:
Prześlij macierz modelu rysowanego obiektu (model Matrix) jako osobna zmienna do vertex shadera (uniform mat4
).
Przemnóż przez te macierz wektor normalny wierzchołka przed przeslaniem go do fragment shadera.
Współrzędna w dopisana do wektora przed mnożeniem przez macierz powinna być ustawiona na 0. Wynika to z tego, ze w przypadku transformacji wektorów reprezentujących kierunki w przestrzeni, nie chcemy dokonywać translacji - np. wektor normalny do powierzchni zależy od orientacji obiektu, ale nie od jego pozycji (przesunięcia) w przestrzeni świata.
specular
). W tym celu:Wyślij pozycje kamery (cameraPos
) jako kolejna zmienna do fragment shadera.
Podobnie jak wektory normalne prześlij z vertex do fragment shadera pozycje wierzchołków (vertexPosition
) w przestrzeni świata (czyli pomnożone przez macierz modelMatrix). Pamiętaj, ze tym razem wektory reprezentują punkty, a nie kierunki - współrzędna w przed mnożeniem musi być ustawiona na 1. W wyniku rasteryzacji otrzymamy w shaderze fragmentu jego pozycję (nazywaną pozycją fragmentu)
Oblicz wektor V (view direction) jako znormalizowaną różnice pozycji kamery i pozycji fragmentu.
Oblicz wektor kierunku odbicia światła R przy użyciu funkcji reflect
. Pamiętaj, żeby przesłać do funkcji odwrócony wektor kierunku światła.
Oblicz natężenie: iloczyn skalarny V i R, przycięty do zera ( max(...,0.0)
), a następnie podniesiony do wysokiej potęgi (np. 8, 50, 1000), która jest miara połyskliwości powierzchni
objectColor * diffuse + vec3(1.0) * specular
. Oznacza to najprostszy przypadek, gdy kolor światła odbitego jest biały.Niech przynajmniej jedna planeta ma księżyce.
Zamiast przesyłać (w lightDir
) kierunek światła, prześlij pozycję słońca do fragment shadera (taką jak ustawiłeś w punkcie powyżej) jako uniform vec3 (nazwij go lightPos
).
Oblicz kierunek światła odejmując od pozycji fragmentu pozycję światła, znormalizuj wynik. Zapisz wynik w zmiennej lightDir
.
Słońce będzie czarne, nie martw się tym, tylko spójrz na punkt następny
Celem tego zadania jest stworzenie shadera (shader_4_sun.vert_ i shader_4_sun.frag), który będzie odpowiadał wyłącznie za rysowanie słońca. Poprzednie shadery (shader_4_1.vert_ i shader_4_1.frag) nadal mają rysować pozostałe obiekty. a) zainicjalizuj program (shadery): - Pliki shader_4_sun.vert i shader_4_sun.frag są identyczne jak 4_1 przed zmianami, będą punktem wyjścia dla shadera słońca.
GLuint programSun
na adres shadera słońca. Stwórz program za pomocą shaderLoader.CreateProgram
analogicznie jak tworzy się program
z shader_4_1.vert i shader_4_1.frag (parametry wejściowe to ścieżka do shadera wierzchołków i fragmentów shader_4_sun.vert i shader_4_sun.frag).drawObject
korzysta z globalnej zmiennej program
, żeby wskazywać shadery do rysowania. Dodaj argument do funkcji, który będziesz przekazywać adres programu, który ma być wykorzystany do rysowania.drawObject
Na poniższym obrazku jest zdjęcie słońca. jest ono ciemniejsze na brzegach spróbuj uzyskać podobny efekt. Przydadzą się wektory z poprzednich punktów, jak wektor normalny i wektor V.