Shadertoy ist eine Programmierumgebung und Community für Leute, die sich wie ich für Mathematik und Programmierung von virtuellen Welten begeistern können. Dabei kommt die Programmiersprache GLSL zum Einsatz, die Sprache der Grafikprozessoren.
Ich hatte mich Anfang Dezember 2024 als Nutzer Svenofnine angemeldet und angefangen, allein mit Mathe und Code Echtzeit-Animationen zu programmieren.
Der Reiz dabei ist auch, dass man immer den Quelltext sieht und sich mit anderen darüber auszutauschen kann. Es ist erstaunlich, was manche da auf den Screen zaubern.
Was ist Shadertoy?
Shadertoy ist eine englischsprachige Programmierumgebung für sogenannte Shader (Schattierer). Rechts schreibt man ein Programm in der Sprache GLSL, das dann beim Drücken auf den »►«-Knopf direkt im Browser kompiliert und von den Shader-Prozessoren der Grafikkarte ausgeführt wird. Das, was links so aussieht wie ein Videofenster ist tatsächlich das Fenster in die mit dem Code erschaffene Welt, mit den Kontrollen über Zeit und Raum darunter. Rechts gibt es noch Knöpfe für das Mitschneiden als Video, Lautsprecher ein/aus und Vollbild.
Doch wie errechnet man anhand der Pixelkoordinate eine Farbe und warum und vor allem wie können alle Pixel gleichzeitig errechnet werden? Dazu habe ich unter https://www.shadertoy.com/view/XXKcR1 ein einfach gehaltenes Beispiel erstellt. Es ist nicht sonderlich spetakulär, es soll nur zeigen, worum es geht:
mit
Die Challenge dabei ist, eine Funktion »mainImage()« zu schreiben, welche für eine gegebene Pixelkoordinate (Pixel_XY) und die abgelaufene Zeit die Farbe errechnet. Die wird dann »einfach« von der Grafikkarte für alle möglichen Pixelkoordinaten möglichst gleichzeitig aufgerufen und errechnet so recht fix die Farbwerte aller Pixel eines Animationsbildes. Im Idealfall passiert das mit der Geschwindigkeit der eingestellten Bildwiederholrate, bei mir sind es 60 Mal pro Sekunde.
Als Programmierer sitzt man quasi in dieser Funktion mainImage() drin. Neben den Koordinaten XY bekommt man von außen noch Lesezugriff auf sogenannte Uniform-Variablen für Auflösung, Zeit, Mausposition u. a. von der Host-Anwendung, welche ja für alle Pixel eines Frames gleich sind.
Mein Beispiel zeigt einen roten gefüllten Kreis an, indem es für jede Pixelkoordinate entscheidet, ob sie auf diesem Kreis liegt oder nicht. Die Formel in Zeile 12 errechnet dafür den Abstand zwischen Pixelkoordinate und Kreismitte. Ist er kleiner als der Radius, wird 1 zurückgeliefert, ansonsten 0.
Der ermittelte Wert wird dann mit allen drei Komponenten der Kreisfarbe (rot, grün, blau) multipliziert und der Pixelfarbe zugewiesen (Zeile 18).
Das macht ein Shader: Pixelkoordinate rein, Pixelfarbe raus. Das geschieht dann künstlerisch gestalteten Wegen vom Betrachter aus durch bewegliche Distanzfelder, Oberflächen mit Texturen und Reflexionen in verzerrten Räumen. Das kann alles sein, was sich berechnen lässt. Die Funktionen für das Rechnen mit Vektoren, Matritzen und Fließkommazahlen sind in den Grafikprozessoren direkt verdrahtet. Die warten drauf!
Das hat mir geholfen
Das »Book Of Shaders« setzt wirklich am Anfang an und erklärt in einfacher Sprache und Handzeichnungen, wie das Ganze im Grunde funktioniert.
Youtube-Video »Lean to Paint with Mathematics« von Nutzer iq ist eine gute Einführung in das Tool Shadertoy und Nutzer FabriceNeyret2 zeigt auf seinem Blog Shadertoy Unofficial, was damit alles möglich ist. Vorweg: Grafisch ist alles möglich!
Nachdem etwa eine Woche vergangen war, ließ mich das Thema nicht mehr los und es kribbelte in den Fingern. Das Erzeugen von Bildern und Animationen mit Mathematik und Programmcode war ja schon 2003 mit POV-Ray künstlerisches Werkzeug. Anders als mit dem Raytracer POV-Ray geht es bei Shadern um Echtzeitgrafik, also es müssen 60 Bilder pro Sekunde entstehen, nicht eins in Stunden oder Tagen. Beides behält aber trotzdem in ihrer Verschiedenheit seine Daseinsberechtigung.

Bei den Programmiersprachen, mit welchen ich mich bisher beschäftigt habe, gab es immer Referenzen der Funktionen, Variablen und Operatoren. Bei Shadertoy hatte es eine Weile gedauert, bis ich auf dieses kleine Fragezeichen rechts unten am Rand des Texteditors entdeckte. Klickt man da drauf, gibt es direkt von Shadertoy das Wichtigste auf einer Seite.

Oben am Editor gibt es die »Shader Inputs«. Das sind sogenannte uniforme Variablen, welche für alle Pixel eines Frames konstant sind und zur lesenden Verfügung stehen.
Es gibt neben den bekannten Datentypen float (Fließkomma-Zahl) und int (Ganzzahl) noch verschiedene Vektor‑, Matrix- und Buffer-Datentypen, die auch auf der Hardware der Grafikkarte unterstützt werden.
Dieser Blog-Post ist kein Tutorial, weil ich da ja selbst ganz am Anfang stehe und es viele Ressourcen dafür gibt. Ich versuche, soweit es geht, meinen Code zu kommentieren und Fragen zu beantworten.
Hier sind noch weitere Links zum Thema:
- inspirnathan.com — Shadertoy Tutorial Part 1 — Intro
- Into Shadertoy and Shaders useful links and tips
- OpenGL Shading Language (GLSL) Quick Reference (PDF)
- Ray Marching, and making 3D Worlds with Math
- SimonDev