Dazu definieren wir zwei varying Variablen (vgl. Kapitel 4.3.2), 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 gl_Normal zur Verfügung, diese multiplizieren wir mit der ebenfalls von OpenGL gestellten gl_NormalMatrix. Nun muss noch die Ergebnisposition des Vertex berechnet werden, hierzu wollen wir die Funktion ftransform nutzen, welche einfach die Funktionalität der fixed Function Pipeline nachbildet.
Die eigentliche Beleuchtungfindet dann im Fragment Shader statt:
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 color welche zur Berechnung der Ergebnisfarbe genutzt wird.
Da normal eine interpolierte Variable ist normalisieren wir diese nochmal und speichern das Ergebnis in 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. 5.4) sieht schon deutlich plastischer aus als zum Beispiel der monocolor Shader.