Trójwymiarowa wizualizacja danych przestrzennych
Transkrypt
Trójwymiarowa wizualizacja danych przestrzennych
Marek Kulawiak – Katedra Systemów Geoinformatycznych, Wydział ETI
Trójwymiarowa wizualizacja
danych przestrzennych
Laboratorium 7. OpenGL Shading Language
1
Marek Kulawiak – Katedra Systemów Geoinformatycznych, Wydział ETI
Wprowadzenie
OpenGL Shading Language (w skrócie GLSL) jest językiem programowania wysokiego
poziomu służącego do tworzenia tzw. shaderów, czyli programów wykonywanych na
specjalizowanych procesorach karty graficznej. Użycie shaderów powoduje nadpisanie
domyślnego potoku renderowania bardziej elastycznym rozwiązaniem, zezwalającym m.in.
na dokładniejsze wyliczanie oświetlenia. Najczęściej spotykane są dwa rodzaje shaderów:
vertex shader: wykonywany dla każdego wierzchołka modelu
fragment/pixel shader: wykonywany dla każdego fragmentu zrasteryzowanego obrazu,
czyli w uproszczeniu dla każdego piksela będącego częścią danego modelu
Użycie shaderów dla danego obiektu powoduje nadpisanie jego domyślnego materiału.
Poniżej przedstawiono przykład bardzo prostej pary shaderów, której zastosowanie
spowoduje pokolorowanie obiektu jednolitym, czerwonym kolorem:
// Vertex Shader
void main(void)
{
// Wyznaczenie położenia wierzchołka.
gl_Position = ftransform();
}
•
•
// Fragment Shader
void main(void)
{
// Przypisanie koloru fragmentowi obrazu.
gl_FragColor = vec4(1.0,0.0,0.0, 1.0);
}
W OpenGL istnieje mechanizm umożliwiający komunikację głównego programu z shaderami
za pomocą specjalnych rodzajów zmiennych, takich jak:
uniform: umożliwia przekazanie danej wartości z programu głównego do shaderów
varying: pozwala na zdefiniowanie pewnych wartości w vertex shaderze, które będą
dostępne we fragment shaderze w zinterpolowanej postaci
Poniżej zamieszczono przykład nieco bardziej złożonej pary shaderów, wykorzystującej
kolory wierzchołków oraz zmienną alpha przekazaną z głównego programu:
// Vertex Shader
varying vec4 vColor;
void main(void)
{
// Wyznaczenie położenia wierzchołka.
gl_Position = ftransform();
// Zapisanie koloru wierzchołka do zmiennej vColor.
vColor = gl_Color;
}
•
•
2
Marek Kulawiak – Katedra Systemów Geoinformatycznych, Wydział ETI
// Fragment Shader
uniform float alpha;
varying vec4 vColor;
void main(void)
{
// Przypisanie aktualnemu fragmentowi obrazu
// automatycznie zinterpolowanego koloru wierzchołka.
gl_FragColor = vec4(vColor.rgb, alpha);
}
Pojawiające się w powyższym kodzie wektory (vec4) to nic innego jak jednowymiarowe
tablice. Język GLSL oferuje wiele udogodnień w zakresie operowania wektorami,
np. gdybyśmy chcieli pobrać wartość zielonej składowej wektora vColor, moglibyśmy to
uczynić na kilka różnych sposobów:
• vColor[1]
• vColor.g
• vColor.y
• vColor.t
Shadery dają znacznie więcej możliwości niż dokładniejsza symulacja oświetlenia – na
niniejszym laboratorium zostaną one wykorzystane m.in. w celu stworzenia prostej animacji,
a także urozmaicenia obrazu sceny o efekty specjalne (tzw. post-processing).
Zadanie 0.
Zapoznaj się z plikiem źródłowym klasy Triangle, a także z kodem wykorzystywanej przez
niej shaderów. Następnie przyjrzyj się zawartości plików ScreenVertex.glsl oraz
ScreenFragment.glsl w celu sprawdzenia, w jaki sposób można skorzystać z tekstury
w GLSL.
Zadanie 1. (1 punkt)
Zmodyfikuj zawartość plików BoxVertex.glsl oraz BoxFragment.glsl w taki sposób, żeby
obecny na scenie obiekt klasy TexturedBox był oświetlony, a także miał na siebie nałożoną
prawidłowo zmapowaną teksturę.
Wskazówka: przypisz fragmentowi odpowiedni kolor w następujący sposób:
gl_FragColor = texture2D(texture, textureCoordinates) * vColor;
Zadanie 2. (1 punkt)
Przepisz odpowiednio kod klasy AlphaQuad, aby korzystała ona z shaderów QuadVertex.glsl
oraz QuadFragment.glsl. Następnie zmodyfikuj kolor fragmentu w taki sposób, żeby obiekt
klasy AlphaQuad wyglądał podobnie jak na poniższym obrazku:
3
Marek Kulawiak – Katedra Systemów Geoinformatycznych, Wydział ETI
Zadanie 3. (1 punkt)
Zmodyfikuj zawartość pliku GridVertex.glsl w taki sposób, żeby wartość składowej y
położenia
wierzchołków
(przed
przemnożeniem
go
przez
macierz
gl_ModelViewProjectionMatrix) była wyliczana według poniższego wzoru:
y = 10.0 * ( sin( 0.1*(gl_Vertex.x)+angle
+ sin( 0.1*(gl_Vertex.z)+angle) );
Następnie modyfikuj składowe zmiennej vColor w taki sposób, żeby wierzchołki znajdujące
się na wzniesieniach były żółte, a te będące częścią wgłębień były koloru niebieskiego. Efekt
końcowy powinien być podobny jak na poniższym obrazku:
Zadanie 4. (0,5 punktu)
(Wymaga wykonania zadania 3.)
Spraw, aby wartość zmiennej angleUniformValue w klasie Grid zmieniała się w czasie,
tworząc w ten sposób prostą animację siatki.
Zadanie 5. (0,5 punktu)
Uzupełnij źródło pliku PlotFragment.glsl w taki sposób, żeby na obiekcie klasy PlotQuad
rysowany był wykres funkcji sinus.
4
Marek Kulawiak – Katedra Systemów Geoinformatycznych, Wydział ETI
Zadanie 6. (1 punkt)
Dodaj do sceny efekt znajdowania się pod wodą. W tym celu musisz:
•
•
nadać zmiennej applyPostProcessing w klasie WorldMain wartość true
przepisać zawartość pliku ScreenFragment.glsl w taki sposób, żeby:
▪
•
składowa x wektora coords zmieniała się w czasie, powodując falowanie obrazu
▪ piksele obrazu nabrały niebieskiego odcienia
odpowiednio modyfikować wartość zmiennej underwaterTime w klasie WorldMain
Przykładowe zadania poprawkowe:
1. Przepisz kod shadera QuadVertex.glsl w taki sposób, żeby korzystające z niego
obiekty stały się billboardami. (1 punkt)
Dodatkowe informacje
1. GLSL Tutorial von Lighthouse3D:
http://zach.in.tu-clausthal.de/teaching/cg_literatur/glsl_tutorial/
2. Basic shading:
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-8-basic-shading/
3. OpenGL 4 Shaders: http://antongerdelan.net/opengl/shaders.html
4. GLSL: An Introduction: http://nehe.gamedev.net/article/glsl_an_introduction/25007/
5. Data Type (GLSL): https://www.opengl.org/wiki/Data_Type_%28GLSL%29
6. OpenGL Programming/Post-Processing:
http://en.wikibooks.org/wiki/OpenGL_Programming/Post-Processing
5