Start · Sprachen · JavaScript · Referenz · WebGLRenderingContext.getShaderInfoLog()

WebGLRenderingContext.getShaderInfoLog()

Methode

Gibt das Informationsprotokoll (Compiler-Meldungen, Fehler, Warnungen) eines <code>WebGLShader</code>-Objekts als String zurück.

seit JavaScript WebGL 1.0 – Baseline: alle modernen Browser Kategorie: webapi

Signatur

WebGLRenderingContext.prototype.getShaderInfoLog(shader)

Beschreibung

Die Methode getShaderInfoLog() liefert das Protokoll, das der GLSL-Compiler beim letzten Aufruf von compileShader() für den angegebenen Shader erzeugt hat. Darin stehen Fehlermeldungen wie Syntaxfehler, nicht deklarierte Variablen oder Typkonflikte, außerdem je nach Treiber auch Warnungen.

Man braucht sie vor allem zum Debuggen: Nach gl.compileShader(shader) fragt man mit gl.getShaderParameter(shader, gl.COMPILE_STATUS) ab, ob das Kompilieren geklappt hat. Wenn nicht, erklärt getShaderInfoLog() den Grund. Ohne diesen Schritt schlägt ein fehlerhafter Shader meist erst später beim Linken oder Zeichnen fehl, und die Ursache ist dann schwer zu finden.

Format und Inhalt des Protokolls legt die Spezifikation nicht fest. Sie hängen von Browser, Grafiktreiber und der Übersetzungsschicht ab (z. B. ANGLE). Typisch sind Zeilen wie ERROR: 0:12: 'foo' : undeclared identifier, wobei 0:12 für Quellstring 0, Zeile 12 steht. Die Methode gibt es genauso in WebGL2RenderingContext.

Parameter

Name Typ Default Beschreibung
$shader Pflicht WebGLShader Das Shader-Objekt (Vertex- oder Fragment-Shader), dessen Protokoll gelesen werden soll. Es wurde vorher mit createShader() erzeugt.

Rückgabewert

Typ
string | null
Beschreibung
Das Compiler-Protokoll als String. Ist nichts zu melden, ist der String meist leer. Geht der Kontext verloren (isContextLost()), wird null zurückgegeben.

Beispiele

Kompilierfehler erkennen und ausgeben

const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');

const source = `
void main() {
  gl_FragColor = vec4(farbe, 1.0); // 'farbe' ist nicht deklariert
}`;

const shader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(shader, source);
gl.compileShader(shader);

if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
  console.error('Shader-Fehler:', gl.getShaderInfoLog(shader));
}
Shader-Fehler: ERROR: 0:3: 'farbe' : undeclared identifier ERROR: 0:3: 'constructor' : not enough data provided for construction

Wiederverwendbare Hilfsfunktion mit Fehlerbehandlung

const compileShader = (gl, type, source) => {
  const shader = gl.createShader(type);
  gl.shaderSource(shader, source);
  gl.compileShader(shader);

  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    const log = gl.getShaderInfoLog(shader);
    gl.deleteShader(shader); // Ressourcen freigeben
    throw new Error(`Kompilieren fehlgeschlagen:\n${log}`);
  }
  return shader;
};

const gl = document.createElement('canvas').getContext('webgl');
const vs = compileShader(gl, gl.VERTEX_SHADER, `
attribute vec4 aPosition;
void main() { gl_Position = aPosition; }`);
console.log('Vertex-Shader OK:', gl.isShader(vs));
Vertex-Shader OK: true

Fehlerzeilen im Quelltext markieren

const reportShaderError = (gl, shader, source) => {
  const log = gl.getShaderInfoLog(shader) ?? '';
  const lines = source.split('\n');
  // Zeilennummern aus Mustern wie 'ERROR: 0:12:' herausziehen
  for (const [, line, msg] of log.matchAll(/ERROR: \d+:(\d+): (.*)/g)) {
    const nr = Number(line);
    console.error(`Zeile ${nr}: ${msg}\n  > ${lines[nr - 1]?.trim()}`);
  }
};

const gl = document.createElement('canvas').getContext('webgl');
const src = 'void main() {\n  gl_FragColor = vec3(1.0);\n}';
const fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fs, src);
gl.compileShader(fs);
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) reportShaderError(gl, fs, src);
Zeile 2: '=' : dimension mismatch > gl_FragColor = vec3(1.0);

// Wichtig · Fallstricke

  • Kein verlässliches Format: Wortlaut und Aufbau der Meldungen unterscheiden sich je nach Browser, Betriebssystem und GPU-Treiber. Ob das Kompilieren geklappt hat, sollte man nicht daran festmachen, ob das Protokoll leer ist. Maßgeblich ist getShaderParameter(shader, gl.COMPILE_STATUS).
  • Das Protokoll kann auch nach erfolgreichem Kompilieren Text enthalten, zum Beispiel Warnungen.
  • Fehler beim Linken (etwa nicht passende varying-Variablen zwischen Vertex- und Fragment-Shader) stehen hier nicht. Dafür gibt es getProgramInfoLog().
  • Leistung: Abfragen wie getShaderParameter und getShaderInfoLog können die GPU-Pipeline synchronisieren. Bei vielen Shadern sollte man erst alle kompilieren und linken und den Status danach abfragen. Mit der Erweiterung KHR_parallel_shader_compile lässt sich auch asynchron prüfen.
  • Ist der Kontext verloren, wird null zurückgegeben. Ein Zugriff wie log.length sollte das abfangen.
  • Gibt man Protokolle in Produktionsumgebungen aus, können sie Hinweise auf Treiber und Hardware verraten, die sich zum Fingerprinting nutzen lassen. In Produktion also sparsam protokollieren.
  • Kompatibilität: Die Methode ist in allen Browsern mit WebGL 1 oder WebGL 2 verfügbar.