\chapter{Shader}

    Nachdem der Boxcode zum Laden und Binden von Shadern nun fertig ist können wir endlich
    unsere eigenen Shader schreiben und ausführen. Alle Shader in diesem Kapitel sind
    stark von \cite{lighthouse3d} inspiriert.

    \section{Monocolor Shader}
    Der wohl einfachste Shader ist der welcher die Vertices unverändert lässt und einfach 
    alle Fragmente auf eine bestimmte Farbe setzt.

    Der komplette Source dieses Shaders ist in den Dateien im Verzeichnis \emph{shader/monocolor}
    zu finden. Ausgeführt wird er mittels 

    ./gltut shader/monocol/monocol.avp shader/monocol/monocol.afp
    respektive

    ./gltut shader/monocol/monocol.avs shader/monocol/monocol.afs

        \subsection{ARB Program Monocolor Shader}
        Zunächst soll die Umsetzung dieses Vorhabens mittels der ARB Programs Extensions
        gezeigt werden:

        \begin{lstlisting}[name=monocolor.avp]
!!ARBvp1.0
PARAM mvp[4] = { state.matrix.mvp };

DP4 result.position.x, mvp[0], vertex.position;
DP4 result.position.y, mvp[1], vertex.position;
DP4 result.position.z, mvp[2], vertex.position;
DP4 result.position.w, mvp[3], vertex.position;

END
        \end{lstlisting}
        ARB Vertex Programs werden immer mit \emph{!!ARBvp} gefolgt von einer Versionsnummer
        eingeleitet. Danach wird
        hier eine Variable namens \emph{mvp} bekannt gemacht welche vom Typ \emph{PARAM}
        ist und somit eine Variable die von OpenGL vorbelegt wird. Variablen sind immer
        Vierkomponenten-Vektoren bestehend aus Floats. In diesem Fall handelt es sich um
        ein Array von vier dieser Vektoren die mit den Komponenten der ModelviewProjection-Matrix 
        - dem Ergebnis der Multiplikation der Modelview- mit der Projektions-Matrix - 
        vorbelegt werden.

        Mit dem Befehl \emph{DP4} wird ein Punktprodukt von zwei Vierkomponenten-Vektoren
        erzeugt und im ersten Operanden gespeichert.

        Die Variable \emph{vertex} enthält den Vertex auf dem der Shader gerade ausgeführt 
        wird, die Variable \emph{result} ist der Ergebnisvertex.

        In diesem Shader wird die Position des Vertex einfach mit der ModelviewProjection-Matrix 
        (ab jetzt kurz MVP genannt) multipliziert und in result gespeichert.

        Das zugehörige Fragment Program gestaltet sich folgendermaßen:

        \begin{lstlisting}[name=monocolor.afp]
!!ARBfp1.0
PARAM c[1] = { { 0, 1 } };
MOV result.color, c[0].xxyy;
END
        \end{lstlisting}

        ARB Fragment Programs werden immer mit \emph{!!ARBfp} eingeleitet, auch hier gefolgt
        von einer Versionsnummer. Nachdem eine Variable namens \emph{c} mit konstanten Werten
        vorbelegt wurde wird die Farbe des Ergebnisfragmentes \emph{result} auf {0.0, 0.0, 1.0, 1.0}
        - also blau - gesetzt.

        \subsection{GLSL Monocolor Shader}
        Nachdem wir den Shader jetzt mittels der ARB Programs umgesetzt haben wollen wir ihn auch
        in GLSL schreiben:

        \begin{lstlisting}[name=monocolor.avs]
void main() {
    vec4 v = vec4(gl_Vertex);       

    gl_Position = gl_ModelViewProjectionMatrix * v;
}
        \end{lstlisting}
        Es ist leicht ersichtlich dass GLSL deutlich eingängiger als der Pseudo-Assembler
        der ARB Programs ist.

        GLSL lehnt sich stark an C an, somit heißt der Einsprungspunkt auch hier \emph{main},
        ist allerdings als \emph{void} definiert. Der Vertex auf dem der Shader ausgeführt wird 
        heißt hier \emph{gl\_Vertex}, die Position des Ergebnisvertexes heißt \emph{gl\_Position}.

        Nun wird hier eine Variable vom Typ \emph{vec4} definiert und mit der Position von gl\_Vertex
        belegt. Die Ergebnisposition ergibt sich einfach aus der Multiplikation der MVP mit diesem
        Vektor.

        Der Source des zugehörigen Fragment Shaders ist ähnlich einfach:
        
        \begin{lstlisting}[name=monocolor.avs]
void main() {
	vec4 color = vec4(0.0, 0.0, 1.0, 1.0);
		
	gl_FragColor = color;
}
        \end{lstlisting}
        Auch hier heißt der Einsprungspunkt main, die Ausgabefarbe des Fragmentes auf dem
        der Shader ausgeführt wird heißt \emph{gl\_FragColor}. Wieder wird eine Variable definiert,
        allerdings wird sie hier einfach mit konstanten Werten für blau belegt. Die Ergebnisfarbe
        ergibt sich einfach aus diesen Werten.

        \begin{figure}
            \centering
            \includegraphics{images/monocolor}
            \caption{Der monocolor Shader in seiner gesamten Pracht}
            \label{fig:monocolor}
        \end{figure}
        

    \section{Flat Shader}
    Unser erster nächster Shader soll nun auch Vertices im Stream verändern, das war
    ja der Sinn der Übung. Die einfachste Änderung ist das flachdrücken des Teapot,
    sprich alle Koordinaten einer Achse auf 0 zu setzen.

    Der Source dieser Shader liegt im Verzeichnis \emph{shader/flat}, ausgeführt wird er mittels

    ./gltut shader/flat/flat.avp shader/monocol/monocol.afp beziehungsweise mit
    
    ./gltut shader/flat/flat.avs shader/monocol/monocol.afs für die GLSL Version
          

        \subsection{ARB Program Flat Shader}
        Auch hier wollen wir zuerst den schweren Weg gehen und den Shader mittels
        der ARB Vertex Programs umsetzen:

        \begin{lstlisting}[name=flat.avp]
!!ARBvp1.0
PARAM mvp[4] = { state.matrix.mvp };
TEMP v;

MOV v.x, vertex.position.x;
MOV v.y, 0.0;
MOV v.z, vertex.position.z;
MOV v.w, vertex.position.w;

DP4 result.position.x, mvp[0], v;
DP4 result.position.y, mvp[1], v;
DP4 result.position.z, mvp[2], v;
DP4 result.position.w, mvp[3], v;

END
        \end{lstlisting}
        Dieser Shader gestaltet sich schon deutlich komplizierter als sein Vorgänger.
        Nach dem üblichen Header und der Bekanntmachung der MVP wir eine Variable \emph{v} 
        definiert die wieder zur Berechnung der Ergebnisposition eingesetzt wird. Nun
        wird jede Komponente von v mit der entsprechenden Komponente aus der Vertexposition
        belegt, bis auf eine, welche einfach auf 0.0 gesetzt wird.
        Anschließend wird auf bekannte Weise die Ergebnisposition aus v und der MVP berechnet.

        Als Fragment Shader nutzen wir einfach den monocolor Shader aus dem vorherigen
        Kapitel.

        \subsection{GLSL Flat Shader}
        Die Implementation dieses Shaders in GLSL ist wieder deutlich eingängiger:
        
        \begin{lstlisting}[name=flat.avs]
void main() {
    vec4 v = vec4(gl_Vertex);       

    v.y = 0.0;

    gl_Position = gl_ModelViewProjectionMatrix * v;
}
        \end{lstlisting}

        Der Unterschied zum Vertex Shader aus dem vorherigen Kapitel liegt hier einfach darin 
        dass dem Vektor v aus dem die Ergebnisposition berechnet wird eine Komponente auf 0.0 
        gesetzt wird bevor wir ihn mit der MVP multiplizieren.

        Auch hier verwenden wir wieder einfach den monocolor Fragment Shader aus dem 
        vorherigen Kapitel. Abbildung \ref{fig:flat} zeigt das Ergebnis.
        
        \begin{figure}
            \centering
            \includegraphics{images/flat}
            \caption{Der flat Shader}
            \label{fig:flat}
        \end{figure}
        
    \section{Flag Shader}
    \label{sec:flag}
    Nun wollen wir den Vertex Shader noch etwas interessanter gestalten, indem wir die zu verändernde
    Komponente der Position der Vektoren nicht nur auf eine Konstante setzen, sondern sie nach einer
    Sinusfunktion verschieben, was den Eindruck einer Fahne erzeugen soll.
        
        \subsection{GLSL Flag Shader}
        Die Umsetzung dieses Vorhabens ist mit der GLSL kein Problem, da sie für alle wichtigen
        geometrischen Funktionen eigene Methoden vordefiniert:

        \begin{lstlisting}[name=flag.avs]
void main() {
    vec4 v = vec4(gl_Vertex);       

    v.y = sin(5.0*v.x)*0.2;

    gl_Position = gl_ModelViewProjectionMatrix * v;
}
        \end{lstlisting}
        
        Die Änderungen am Shader des letzten Kapitels nehmen sich wieder sehr gering aus,
        die zu verändernde Komponente des Vektors wird einfach mittels der Funktion sin()
        in Abhängigkeit vom Wert der ersten Komponente gesetzt. Die beiden eingeführten
        Faktoren (5.0 und 0.2) dienen lediglich dazu die Veränderung deutlicher zu machen.

        Das resultierende Bild lässt den gewünschten Effekt zwar erkennen, aber leider nur undeutlich.
        Dies liegt daran, dass in der Szene trotz der von uns gesetzten direktionalen Lichtquelle die 
        Beleuchtung komplett fehlt, da wir die fixed Function Pipeline mit unseren Shadern umgangen 
        haben, folglich müssen wir uns jetzt selbst um die Beleuchtung kümmern.

        \begin{figure}
            \centering
            \includegraphics{images/flag}
            \caption{Der flag Shader setzt eine Komponente nach einer Sinusfunktion}
            \label{fig:flag}
        \end{figure}

    \section{Toon Shader}
    Beleuchtung bedeutet dass die einzelnen Fragmente eines Polygons je nach Lichteinfall in der 
    Farbe verändert werden. Hierzu ist es notwendig den Winkel zu bestimmen in dem das Licht
    der Lichtquelle auf das Fragment trifft. Dies soll anhand eines ersten einfachen Versuches
    eine korrekte Beleuchtung zu simulieren demonstriert werden, dem Toon Shader:

        \subsection{GLSL Toon Shader}
        Um den angesprochenen Winkel zu berechnen muss die Richtung bekannt sein aus der das Licht
        kommt. Dies geschieht hauptsächlich im Vertex Shader:
        
        \begin{lstlisting}[name=toon.avs]
varying vec3 lightDir,normal;

void main()
{
	lightDir = normalize(vec3(gl_LightSource[0].position));
	normal = gl_NormalMatrix * gl_Normal;

	gl_Position = ftransform();
} 
        \end{lstlisting}
        
        Dazu definieren wir zwei \emph{varying} Variablen (vgl. Kapitel \ref{sec:vars}), eine
        um die Richtung des einfallenden Lichtes zu speichern (lightDir), und eine für die Normale des
        Vertex auf welchem operiert wird (normal). Die von der Applikation definierten Lichtquellen hält
        OpenGL für uns in einem Array namens gl\_LightSource vor.
        Die Richtung des Lichtes einer direktionalen Lichtquelle ist einfach ihre \"Position\",
        um sicher zu gehen normalisieren wir diese also und errechnen so lightDir.
        Die Vektornormale stellt OpenGL für uns in der Variablen \emph{gl\_Normal} zur Verfügung,
        diese multiplizieren wir mit der ebenfalls von OpenGL gestellten \emph{gl\_NormalMatrix}.
        Nun muss noch die Ergebnisposition des Vertex berechnet werden, hierzu wollen wir die
        Funktion \emph{ftransform} nutzen, welche einfach die Funktionalität der fixed Function
        Pipeline nachbildet.

        Die eigentliche \"Beleuchtung\" findet dann im Fragment Shader statt:

        \begin{lstlisting}[name=toon.afs]
varying vec3 lightDir,normal;

void main()
{

	float intensity;
	vec4 color;
	
	// normalizing the lights position to be on the safe side
	
	vec3 n = normalize(normal);
	
	intensity = dot(lightDir,n);
	
    if (intensity > 0.99) 
		color = vec4(0.9, 0.9, 1.0, 1.0);
	else if (intensity > 0.95)
		color = vec4(0.7, 0.7, 1.0, 1.0);
	else if (intensity > 0.5)
		color = vec4(0.3, 0.3, 0.6, 1.0);
	else if (intensity > 0.25)
		color = vec4(0.2, 0.2, 0.4, 1.0);
	else
		color = vec4(0.1, 0.1, 0.2, 1.0);
	
	gl_FragColor = color;
} 
        \end{lstlisting}

        Hier machen wir zuerst die varying Variablen lightDir und normal bekannt.
        In main deklarieren wir dann eine Variable welche die Intensität des einfallenden
        Lichtes abhängig vom Einfallswinkel des Lichtes halten soll, und eine Variable \emph{color}
        welche zur Berechnung der Ergebnisfarbe genutzt wird.

        Da normal eine interpolierte Variable ist normalisieren wir diese nochmal und speichern
        das Ergebnis in \emph{n}. Dann berechnen wir die Intensität aus dem Punktprodukt der
        interpolierten Lichtrichtung und n. Anschließend setzen wir einfach abhängig von dieser
        Intensität die Farbe des Fragmentes in 5 Stufen. Das Ergebnis 
        (./gltut shader/toon/toon.avs shader/toon/toon.afs, siehe Abb. \ref{fig:toon})
        sieht schon deutlich plastischer aus als zum Beispiel der monocolor Shader.
        
        \begin{figure}
            \centering
            \includegraphics{images/toon}
            \caption{der Toon Shader, ein simpler Ansatz der Beleuchtung}
            \label{fig:toon}
        \end{figure}

    \section{Flagge, die 2.}
    \label{sec:flagnormals}
    Fuhren wir nun den eben geschriebenen Toon-Shader zusammen mit dem Flag-Shader aus Kapitel \ref{sec:flag}
    aus ist das Ergebnis ziemlich unbefriedigend - das liegt daran dass der Flag-Shader die Variable normal
    nicht setzt. Das wollen wir ändern.

        \subsection{GLSL Flag Shader mit Normalen}
        Die Änderungen zum ersten Flag Shader nehmen sich wieder sehr gering aus:

        \begin{lstlisting}[name=flagnormals.avs]
varying vec3 lightDir,normal;

void main()
{
	lightDir = normalize(vec3(gl_LightSource[0].position));
	
    vec4 v = vec4(gl_Vertex);       
    v.y = sin(v.x);

    vec3 n = normalize(vec3(1/cos(v.x), 1.0f, 0.0f));
    normal = gl_NormalMatrix * n;
    
    gl_Position = gl_ModelViewProjectionMatrix * v;
} 
        \end{lstlisting}

        Im Grunde übernehmen wir nur die Variablen lightDir und normal aus dem Toon Shader, normal
        wird allerdings anders belegt. Führt man den Toon Fragment Shader jetzt mit diesem neuen
        Vertex Shader aus 
        
        ./gltut shader/flag/flagnormals.avs shader/toon/toon2.afs 
        
        sieht das Ergebnis schon deutlich besser aus. Die jetzt noch vorhandenen
        Fehler kommen daher, dass GLUT während dem Zeichnen des Teapot leider den Kontext verändert,
        was sich auch auf die gl\_NormalMatrix auswirkt. Das soll uns nicht weiter stören, schließlich
        wurden wir um eine Flagge zu zeichnen normalerweise nicht auf den teapot zurückgreifen.

    \section{Lighting}
    \label{sec:perpixel}
    So - nachdem wir jetzt einen einfachen Ansatz der Beleuchtung implementiert haben wollen wir
    uns daran machen ein komplettes Beleuchtungsmodell zu implementieren wie es die fixed Function Pipeline
    bietet. Mehr noch - wir wollen nicht nur pro Vertex sondern sogar pro Pixel Beleuchten, einfach weil
    der Aufwand nur geringfügig höher ist da unsere Fragment Shader sowieso auf jedem Pixel ausgeführt
    werden. Algorithmen zum per Pixel Lighting sind vielfach beschrieben, ich halte mich in diesem
    Dokument an \cite{redbook}. Allerdings werden wir uns auf direktionales Licht beschränken:
    
        \subsection{GLSL per Pixel Lighting}
        Zu erst der Vertex Shader:

        \begin{lstlisting}[name=perpixel.avs]
varying vec4 diffuse, ambient;
varying vec3 normal, lightDir, halfVector;

void main() {

    // transform normal to eye space
	normal = normalize(gl_NormalMatrix * gl_Normal);

    // normalize light direction
	lightDir = normalize(vec3(gl_LightSource[0].position));

	// normalize the halfVector to pass it to the fragment shader
	halfVector = normalize(gl_LightSource[0].halfVector.xyz);
	
	// compute diffuse and ambient colors
	diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
    ambient = gl_FrontMaterial.ambient * (gl_LightSource[0].ambient + gl_LightModel.ambient);
	
    // transform position
	gl_Position = ftransform();
	
} 
        \end{lstlisting}

        Die Variablen normal und lightDir sollten noch aus den letzten Shadern bekannt sein, neu ist
        \emph{halfVector}. Diese Variable dient der Übergabe des normalisierten Halbvektors - dem Vektor
        der genau zwischen Vektor vom Augenpunkt zum Vertex (eye vector) und dem Lichtvektor liegt - an
        den Fragment Shader. Der Halbvektor wird zur Berechnung des spekulaeren Lichtanteils (specular component)
        genutzt, eine Vereinfachung des Phong-Beleuchtungsmodelles welche zu erst beschrieben in \cite{blinn}.
        Des weiteren deklarieren wir vier-komponentige Vektoren \emph{diffuse} \emph{ambient} die jeweils den 
        diffusen und den ambienten Anteil des Lichtes in diesem Vertex speichern sollen.

        Im eigentlichen Programm berechnen wir zunachst die Normale, die Lichtrichtung und den eben
        beschriebenen Halbvektor. Dann wird der diffuse Lichtanteil berechnet nachdem wir die diffuse Farbe
        des Materiales mit dem diffusen Anteil der Lichtquelle multiplizieren.
        Der ambiente Lichtanteil berechnet sich folglich ganz nach Phong aus der ambienten Farbe des Materiales
        multipliziert mit der Summe der ambienten Lichtanteile der Lichtquelle und des globalen Lichtmodells 
        welches von der Applikation vorgegeben wird.

        Schliesslich transformieren wir nur noch die Position des Vertexes auf bekannte Weise.
        
        Der Fragment Shader ist der bis jetzt komplizierteste:

        \begin{lstlisting}[name=perpixel.afs]
varying vec4 diffuse, ambient;
varying vec3 normal, lightDir, halfVector;

void main() {
	vec3 n, halfV, viewV, ldir;
	float NdotL, NdotHV;

    vec4 color = ambient;

	n = normalize(normal);
	
	// compute the dot product between normal and ldir 
	NdotL = dot(n,lightDir);

	if (NdotL > 0.0) {
		halfV = normalize(halfVector);
		NdotHV = max(dot(n,halfV),0.0);
		color += gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(NdotHV,gl_FrontMaterial.shininess);
		color += diffuse * NdotL;
	}

	gl_FragColor = color;
}
        \end{lstlisting}

        Nachdem wir die im Vertex Shader geschriebenen Variablen bekannt gemacht haben kommen wir zur eigentlichen
        main-Funktion. Dort deklarieren wir einige lokale Variablen welche wir im weiteren Verlauf brauchen werden
        und da wir die varying Variablen nicht im Fragment Shader beschreiben koennen kopieren wir die interpolierte
        Normale und ambiente Farbe in ebenfalls lokale Variablen. 

        Nun da die Vorarbeit geleistet ist kommen wir zur eigentlichen Fragmentfarbe. Dazu berechnen wir zunachst das
        Punktprodukt zwischen der Normalen und der Lichtrichtung. Falls das Punktprodukt groesser ist als 0 muessen wir
        mehr tun als nur die ambiente Farbe zu setzen: In diesem Fall addieren wir zum ambienten Lichtanteil die nach 
        Blinn berechneten spekulaeren und die diffusen Farben. 
        
        Fuehren wir nun diese beiden Shader auf unserem teapot aus 
        (./gltut shader/lighting/perpixel.avs shader/lighting/perpixel.afs)
        ist das Ergebnis (Abb. \ref{fig:perpixel}) doch schon recht ansehnlich.

        \begin{figure}
            \centering
            \includegraphics{images/perpixel}
            \caption{Per Pixel Lighting}
            \label{fig:perpixel}
        \end{figure}
        
    \section{zurueck zur Flagge}
    Nun wollen wir das so eben gelernte auf unsere Flagge anwenden:

        \subsection{GLSL Flag Shader mit per Pixel lighting}
        \label{sec:flaglighting}
        
        Das Erstellen des Vertex Shaders fuer dieses Vorhaben besteht eigentlich nur darin
        dass wir den Flag Shader aus \ref{sec:flagnormals} um die noetigen Komponenten
        aus dem letzten Kapitel (\ref{sec:perpixel}), namentlich dem Halbvektor und die
        interpolierten Farbanteile, erweitern.

        \begin{lstlisting}[name=flaglighting.avs]
varying vec4 diffuse, ambient;
varying vec3 normal, lightDir, halfVector;

void main()
{
    // normalize light direction
	lightDir = normalize(vec3(gl_LightSource[0].position));
	
    vec4 v = vec4(gl_Vertex);       
    v.y = sin(v.x);

    vec3 n = normalize(vec3(1/cos(v.x), 1.0f, 0.0f));
    normal = normalize(gl_NormalMatrix * n);

    // normalize the halfVector to pass it to the fragment shader
    halfVector = normalize(gl_LightSource[0].halfVector.xyz);

    // compute diffuse and ambient colors
    diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
    ambient = gl_FrontMaterial.ambient * (gl_LightSource[0].ambient + gl_LightModel.ambient);
    
    gl_Position = gl_ModelViewProjectionMatrix * v;
} 
        \end{lstlisting}

        An dieser Stelle sollte nichts unbekanntes mehr hinzugekommen sein, wir berechnen
        weiterhin die Lichtrichtung, druecken dann den teapot flach und verformen ihn nach einer
        Sinusfunktion. Danach berechnen wir wieder unsere (falschen) Normalen, geben den
        Halbvektor fuer die Berechnung des spekulaeren Lichtanteiles nach Blinn sowie die
        diffusen und ambienten Farbanteile an den Fragment Shader weiter und transformieren
        die Vertexposition in die Projektionsebene - alles wie gehabt.

        Am Fragment Shader selbst aendert sich logischerweise im Vergleich zum vorherigen Kapitel
        gar nichts. Das Ergebnis (./gltut shader/flag/flaglighting.avs shader/lighting/perpixel.afs)
        sieht zwar aufgrund unserer falschen Normalen nicht wirklich
        realistisch aus, aber dennoch koennen wir die Verformung der Ebene in Abb \ref{fig:flaglighting}
        nun deutlich erkennen.
       
        \begin{figure}
            \centering
            \includegraphics{images/flaglighting}
            \caption{Die Flagge mit per Pixel Lighting}
            \label{fig:flaglighting}
        \end{figure}
        
    \section{wehende Flagge}

    Zum Abschluss wollen wir noch die in Kapitel \ref{sec:glslcomprax} gesetzte, sich ueber die Zeit
    veraendernde, Variable nutzen um unsere Flagge auch zum wehen zu bringen:

        \subsection{GLSL waving flag Shader}
        
        Unsere Flagge soll innerhalb einer Sekunde einmal komplett durchschwingen, sprich wir
        wollen innerhalb dieser Zeitspanne die Sinusfunktion um eine komplette Periode verschieben.
        Hierzu muss lediglich der Vertex Shader aus \ref{sec:flaglighting} ein wenig angepasst werden:

        \begin{lstlisting}[name=flagwave.avs]
const float PI = float(4.0f * atan(1.0f));

// uniform variable set by the application
uniform float timeElapsed;

varying vec4 diffuse, ambient;
varying vec3 normal, lightDir, halfVector;

void main()
{
    // normalize light direction
	lightDir = normalize(vec3(gl_LightSource[0].position));
	
    vec4 v = vec4(gl_Vertex);
    float offset = timeElapsed * 2.0f * PI;
    v.y = sin(v.x + offset);

    vec3 n = normalize(vec3(1/cos(v.x + offset), 1.0f, 0.0f));
    normal = normalize(gl_NormalMatrix * n);

    // normalize the halfVector to pass it to the fragment shader
    halfVector = normalize(gl_LightSource[0].halfVector.xyz);

    // compute diffuse and ambient colors
    diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
    ambient = gl_FrontMaterial.ambient * (gl_LightSource[0].ambient + gl_LightModel.ambient);
    
    gl_Position = gl_ModelViewProjectionMatrix * v;
} 
        \end{lstlisting}
        
        Nachdem wir uns $\pi$ als Konstante definiert haben deklarieren wir die spaeter
        von der Applikation gesetzte uniform-Variable \emph{timeElapsed}. Nun ist die einzige
        noch durchzufuehrende Aenderung die Berechnung der Verschiebung unserer Sinuskurve 
        (\emph{offset}) welche dann sowohl zum Setzen der neuen Position als auch zur Berechnung
        unserer - immernoch falscher - Normalen eingesetzt wird.

        Diesen Vertex Shader kann man nun mit jedem unserer Fragment Shader zusammen benutzen,
        auch wenn bei den beleuchtenden Shadern gerade in der Bewegung doch sehr auffaelt dass
        die Normalen nicht korrekt gesetzt werden.
