# WebGL-Farbverläufe mit Shadern, erklärt für Designer

[Canonical HTML page](https://gradiently.design/de/guide/shader-gradients)

Manche Farbverläufe im Web treiben, leuchten und schimmern auf eine Art, die kein Bild und keine CSS-Regel schafft. Das sind Shader. So funktionieren sie, in Worten, mit denen Designer arbeiten können.

## The short version

- Ein WebGL-Farbverlauf wird von einem Shader gezeichnet: einem kleinen Programm, das auf dem Grafikchip läuft und die Farbe jedes Pixels festlegt, oft viele Male pro Sekunde.
- Weil ein Shader Farbe aus Mathematik berechnet, statt ein gespeichertes Bild zu lesen, kann er Bewegung, Rauschen, Körnung und Licht in jeder Größe hinzufügen, ohne dass die Datei wächst.
- Shader-Farbverläufe kosten mehr Rechenleistung als CSS-Farbverläufe, also pausiert ein guter Shader außerhalb des sichtbaren Bereichs, respektiert reduzierte Bewegung und hat einen schlichten CSS-Fallback.
- Nutze CSS für ruhende Übergänge und einfache Bewegung, und greif zum Shader, wenn Textur, Tiefe oder Bewegung der Kern des Designs sind.

Ein **WebGL-Farbverlauf** ist ein Farbverlauf, den dein Browser mit einem Shader malt: einem kurzen Programm, das auf dem Grafikchip (der GPU) läuft und für jedes Pixel auf dem Bildschirm eine Frage beantwortet: „Welche Farbe hast du gerade?“ Ein CSS-Farbverlauf ist ein festes Rezept aus Farben und Positionen. Ein Shader ist eine Formel, also kann er die Farbe biegen, körnen, leuchten lassen und bewegen, und das sechzigmal pro Sekunde, ohne dass ein Bild heruntergeladen wird.

Du musst keine Shader schreiben, um mit ihnen zu gestalten, aber zu wissen, was sie können und was nicht, hilft dir, Entwickler zu briefen, ein Tool zu beurteilen und zu entscheiden, wann ein schlichter [CSS-Farbverlauf](https://gradiently.design/de/guide/css-linear-gradient) die bessere Wahl ist.

## Was ein Shader ist, in einfachen Worten

WebGL ist der Weg des Browsers, mit der GPU zu sprechen, und jede WebGL-Zeichnung nutzt zwei Arten von Shadern. Der **Vertex-Shader** platziert Formen, bei einem bildschirmfüllenden Farbverlauf ist das nur ein Rechteck über dem Canvas. Der **Fragment-Shader** erledigt die spannende Arbeit: Er läuft einmal pro Pixel, erhält dessen Position und die aktuelle Zeit und gibt eine Farbe zurück.

Weil die GPU Tausende dieser winzigen Programme parallel ausführt, wird eine Formel, die in normalem Code langsam wäre, günstig genug, um jedes Frame neu zu zeichnen. Hier ist ein vollständiger Fragment-Shader für einen dreifarbigen Farbverlauf, dessen Grenze sich mit der Zeit sanft wiegt, mit einer Zeile Körnung obendrauf.

```text
#version 300 es
precision highp float;

uniform vec2 u_resolution;   // canvas size in pixels
uniform float u_time;        // seconds since start
out vec4 outColor;

void main() {
  vec2 uv = gl_FragCoord.xy / u_resolution;   // 0 to 1 across the canvas

  vec3 night  = vec3(0.07, 0.04, 0.18);  // #120a2e
  vec3 violet = vec3(0.49, 0.23, 0.93);  // #7c3aed
  vec3 coral  = vec3(0.98, 0.45, 0.45);  // #fa7373

  // A slow wave bends the blend so the colours drift.
  float wave = sin(u_time * 0.3 + uv.x * 3.0) * 0.08;
  float t = clamp(uv.y + wave, 0.0, 1.0);

  vec3 color = mix(night, violet, smoothstep(0.0, 0.6, t));
  color = mix(color, coral, smoothstep(0.55, 1.0, t));

  // Fine grain: a different random value per pixel, per frame.
  float n = fract(sin(dot(gl_FragCoord.xy + u_time, vec2(12.9898, 78.233))) * 43758.5453);
  color += (n - 0.5) * 0.04;

  outColor = vec4(color, 1.0);
}
```

Ein WebGL2-Fragment-Shader in GLSL. `smoothstep` macht jeden Übergang weich, die Sinuswelle bewegt die Grenze, und die letzten Zeilen fügen Körnung hinzu, die zugleich Banding versteckt.

- Nachtgrund: #120a2e
- Violett: #7c3aed
- Koralle: #fa7373

Die drei Farben im Shader. GLSL schreibt Farbe als 0 bis 1 pro Kanal, also wird #7c3aed zu 124, 58 und 237, jeweils geteilt durch 255.

## Wie sich ein Shader-Farbverlauf von einem CSS-Farbverlauf unterscheidet

Ein CSS-Farbverlauf ist deklarativ: Du listest Farben und Positionen auf, und der Browser malt sie. Meistens ist das das richtige Werkzeug. Ein Shader ist prozedural: Du beschreibst, wie sich Farbe verhalten soll, und die Mathematik erzeugt sie. Dieser Unterschied zeigt sich darin, was beide können und was beide kosten.

| Aspekt | CSS-Farbverlauf | Shader-Farbverlauf |
| --- | --- | --- |
| Definiert durch | Farben, Stopps und eine Richtung | Eine Formel, die pro Pixel läuft |
| Bewegung | Position, Größe oder animierte Custom Properties | Alles, was sich mathematisch ausdrücken lässt, in jedem Frame |
| Textur und Körnung | Braucht eine zusätzliche Ebene, etwa SVG-Rauschen | Eingebaut, und sie kann sich bewegen |
| Laufende Kosten | Sehr gering, sobald gemalt | Hält die GPU beschäftigt, solange er animiert |
| Funktioniert ohne JavaScript | Ja | Nein: Ein Skript richtet den Canvas ein |
| Funktioniert in E-Mails | Teilweise, je nach Mailprogramm | Nein |

Keiner ist grundsätzlich besser. Jeder gewinnt bei einer anderen Aufgabe.

Der CSS-Fallback: `linear-gradient(180deg, #120a2e 0%, #4c1d95 40%, #7c3aed 62%, #fa7373 100%)`

Dieselbe Palette als ruhender CSS-Farbverlauf. Jeder Shader-Hintergrund sollte so einen Fallback mitbringen, sichtbar bevor der Shader startet und immer dann, wenn er nicht laufen kann.

## Warum Shader-Farbverläufe lebendig wirken

Drei Techniken leisten den Großteil der Arbeit, und du wirst hören, wie Entwickler sie nennen. **Noise** ist weicher Zufall: Statt eines geraden Übergangs folgt die Farbe einer Landschaft aus sanften Hügeln, deshalb wirken Shader-Farbverläufe organisch statt geometrisch. **Domain Warping** speist das Rauschen in sich selbst zurück, sodass sich die Farbe faltet und wirbelt wie Tinte im Wasser. **Zeit** schiebt die ganze Landschaft weiter und macht aus einer ruhenden Fläche ein Treiben.

- **Körnung** lässt sich pro Pixel und pro Frame erzeugen, also schimmert sie wie Film, statt stillzuliegen wie eine aufgelegte Textur. Siehe [körnige Farbverläufe](https://gradiently.design/de/guide/grainy-gradients).
- **Licht** lässt sich mit wenigen Zeilen vortäuschen: Ein Glanzlicht, das dem Rauschen folgt, wirkt wie Schimmer auf Seide oder Glas.
- **Auflösung** gibt es gratis. Die Formel läuft in jeder Bildschirmgröße, also bleibt ein Shader-Farbverlauf mit demselben Code auf einem Handy und auf einem 4K-Monitor scharf.
- **Banding** ist leichter zu besiegen, weil der Shader etwas Dithering hinzufügen kann, bevor die Farbe auf 8 Bit gerundet wird. [Banding bei Farbverläufen](https://gradiently.design/de/guide/gradient-banding) erklärt, warum das zählt.

### Nimm CSS, wenn

- Der Farbverlauf ruht oder sich auf eine einfache Art bewegt
- Er auf einer langen Seite hinter viel Text liegt
- Er ohne Skripte oder in E-Mails funktionieren muss
- Du ihn in einer Codezeile brauchst

### Nimm einen Shader, wenn

- Bewegung oder Textur der Kern des Designs sind
- Es um einen Hero-Bereich geht, nicht um jeden Abschnitt
- Du Körnung, Glanz oder Fluss willst, den CSS nicht vortäuschen kann
- Du einen CSS-Fallback und eine Pause liefern kannst

## Was ein bewegter WebGL-Hintergrund kostet

Ein animierender Shader lässt die GPU arbeiten, solange er auf dem Bildschirm ist. Auf einem Desktop merkt man das kaum. Auf einem älteren Handy kann es warme Hände, einen leeren Akku und eine Seite bedeuten, die weniger flüssig scrollt. Die Kosten wachsen mit der Zahl der Pixel und der Komplexität der Formel, also ist ein bildschirmfüllender Shader auf einem hochauflösenden Display der schwerste Fall. [Machen Farbverläufe eine Website langsam](https://gradiently.design/de/guide/css-gradient-performance) zeigt, wie du das misst.

1. **Zeig zuerst den CSS-Fallback** Mal den ruhenden Farbverlauf sofort und blende den Canvas ein, sobald der Shader sein erstes Frame gezeichnet hat. Niemand sollte eine leere Box sehen.
2. **Prüf, ob WebGL verfügbar ist** Manche Browser, Geräte und Datenschutzeinstellungen schalten es ab. Lässt sich der Kontext nicht erzeugen, behalte den Fallback.
3. **Respektiere reduzierte Bewegung** Bittet die Person um weniger Bewegung, zeichne ein Frame und stoppe. [Reduzierte Bewegung](https://gradiently.design/de/guide/reduced-motion) erklärt die Einstellung.
4. **Pausiere, wenn er nicht sichtbar ist** Stoppe die Animationsschleife, wenn der Canvas aus dem Blick scrollt oder der Tab im Hintergrund ist.
5. **Render in sinnvoller Auflösung** Weiche Farbverläufe brauchen selten jedes Gerätepixel. In halber Auflösung zu zeichnen und den Browser hochskalieren zu lassen, kann viel Arbeit sparen, bei einer Unschärfe, die du nicht unterscheiden kannst.

```js
const canvas = document.querySelector('#hero-canvas')
const gl = canvas.getContext('webgl2')
const still = matchMedia('(prefers-reduced-motion: reduce)').matches
let visible = true

if (!gl) {
  canvas.remove() // the CSS gradient behind it stays
} else {
  new IntersectionObserver(([entry]) => {
    visible = entry.isIntersecting
  }).observe(canvas)

  const frame = (ms) => {
    if (visible && !document.hidden) draw(gl, ms / 1000) // your draw call
    if (!still) requestAnimationFrame(frame)
  }
  requestAnimationFrame(frame)
}
```

Die Leitplanken in wenigen Zeilen: ein Fallback, wenn WebGL fehlt, nur ein Frame bei reduzierter Bewegung und kein Zeichnen außerhalb des sichtbaren Bereichs oder in einem verborgenen Tab.

Zum Nachschlagen dokumentiert die [WebGL-API bei MDN](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API) jeden hier genutzten Aufruf, und [caniuse](https://caniuse.com/webgl2) verfolgt die Unterstützung von WebGL2 in den Browsern.

## Einen Shader-Farbverlauf gestalten: was ins Briefing gehört

Du kannst einen Shader lenken, ohne GLSL zu lesen. Brief ihn wie ein Material, nicht wie ein Farbmuster. Nenn die Grundfarbe und die drei bis fünf Farben, die darauf leben, in Hex. Beschreib die Struktur: weiche Pfützen, lange Bänder, gefaltete Seide. Gib das Tempo in Sekunden pro Zyklus an statt „langsam“, denn langsam heißt für jeden etwas anderes. Sag, wie viel Körnung und ob sie sich bewegt. Und sag zuletzt, wo Text sitzen wird, damit der unruhigste Teil der Fläche davon fernbleibt.

> **Beurteile ihn zuerst im Stand** Pausiere den Shader auf einem zufälligen Frame und sieh ihn dir als Standbild an. Sieht ein ruhendes Frame nicht gut aus, rettet ihn auch die Bewegung nicht. Bewegung sollte ein Design ergänzen, das schon funktioniert.

## Wie Gradiently Marks mit Shadern zeichnet

Die Marks von Gradiently sind Shader-Farbverläufe. Jeder Mark ist ein Rezept aus Farben, bis zu drei gestapelten Materialien, Licht, Körnung und Bewegung, und das Studio zeichnet ihn live mit WebGL2 hinter alles, was du gestaltest. Weil er berechnet statt gespeichert wird, rendert derselbe Mark in jeder Plattformgröße scharf und bewegt sich, wenn du ein Loop-Video exportierst. Der Renderer weiß außerdem, wo deine Worte stehen, und kann den ruhigsten Teil der Fläche dahinter schieben. [Was ist ein Mark](https://gradiently.design/de/guide/what-is-a-mark) erklärt das Rezept vollständig.

Ein Mark ist ein Shader-Rezept mit einem Namen, einem Code und einem Besitzer. Seine Seite zeigt ihn live gerendert.

## FAQ

### Was ist ein WebGL-Farbverlauf?

Ein Farbverlauf, den ein Shader zeichnet, ein kleines Programm auf dem Grafikchip, das die Farbe jedes Pixels berechnet. Weil er eine Formel ist, kann er sich bewegen, Körnung hinzufügen und in jeder Größe rendern.

### Ist ein Shader-Farbverlauf schlecht für die Performance?

Ein ruhender oder pausierter Shader kostet wenig, ein animierender hält die GPU beschäftigt, solange er sichtbar ist. Pausiere ihn außerhalb des Blickfelds, zeichne in sinnvoller Auflösung und behalte einen CSS-Fallback.

### Kann ich einen Shader-Farbverlauf ohne Programmieren erstellen?

Ja. Mehrere Design-Tools erzeugen Shader-Hintergründe über Regler, und die Forge von Gradiently baut Marks, also Shader-Farbverläufe, aus einem Satz oder Regler für Regler.

### Respektieren Shader-Farbverläufe die Einstellung für reduzierte Bewegung?

Nur, wenn sie dafür gebaut sind. Prüf die Media Query prefers-reduced-motion in JavaScript und zeichne ein einzelnes Standbild, wenn sie gesetzt ist.

### Was ist GLSL?

GLSL ist die Shader-Sprache, die WebGL nutzt. Darin geschriebene Fragment-Shader legen die Farbe jedes Pixels fest, und der Browser kompiliert sie für den Grafikchip.
