Signatur
Beschreibung
Mit getFragDataLocation() fragst du in einem bereits gelinkten Shader-Programm ab, an welche Farbnummer eine out-Variable des Fragment-Shaders gebunden ist. Diese Nummer entspricht dem Index in der Liste, die du an drawBuffers() übergibst, also z. B. gl.COLOR_ATTACHMENT0 + n eines Framebuffers.
Nützlich ist die Methode vor allem bei Multiple Render Targets (MRT), etwa beim Deferred Shading. Dort schreibt ein Fragment-Shader gleichzeitig in mehrere Ausgaben (Albedo, Normalen, Position). Anhand der zurückgegebenen Nummern ordnest du jeder Ausgabe die richtige Textur im Framebuffer zu.
In WebGL 2 legst du die Nummern meist direkt im Shader mit layout(location = N) out vec4 ...; fest. Anders als in Desktop-OpenGL gibt es in WebGL 2 kein bindFragDataLocation(). Die Methode dient also nur zum Abfragen, zum Beispiel zur Kontrolle oder wenn es nur eine einzige Ausgabe ohne layout-Angabe gibt (die bekommt dann automatisch 0).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $program Pflicht | WebGLProgram | Das Shader-Programm, das schon erfolgreich mit linkProgram() gelinkt wurde. |
|
| $name Pflicht | string | Der Name der out-Variable im Fragment-Shader, z. B. "outColor". |
Rückgabewert
GLint mit der Farbnummer, die an die Variable gebunden ist. Den Wert -1 bekommst du, wenn die Variable nicht existiert, keine out-Variable ist oder der Name mit dem reservierten Präfix gl_ oder webgl_ beginnt.Beispiele
Einfache Abfrage einer Fragment-Ausgabe
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2');
const vsSource = `#version 300 es
in vec4 aPosition;
void main() { gl_Position = aPosition; }`;
const fsSource = `#version 300 es
precision highp float;
out vec4 outColor;
void main() { outColor = vec4(1.0, 0.0, 0.0, 1.0); }`;
const compile = (type, src) => {
const shader = gl.createShader(type);
gl.shaderSource(shader, src);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(shader));
}
return shader;
};
const program = gl.createProgram();
gl.attachShader(program, compile(gl.VERTEX_SHADER, vsSource));
gl.attachShader(program, compile(gl.FRAGMENT_SHADER, fsSource));
gl.linkProgram(program);
console.log(gl.getFragDataLocation(program, 'outColor'));
MRT: Ausgaben eines G-Buffers prüfen (Deferred Shading)
// program wurde mit diesem Fragment-Shader gelinkt:
// #version 300 es
// precision highp float;
// layout(location = 0) out vec4 gAlbedo;
// layout(location = 1) out vec4 gNormal;
// layout(location = 2) out vec4 gPosition;
const outputs = ['gAlbedo', 'gNormal', 'gPosition'];
const locations = outputs.map((name) => gl.getFragDataLocation(program, name));
console.log(locations);
// Draw-Buffers passend zu den Farbnummern setzen
const buffers = [];
locations.forEach((loc) => {
buffers[loc] = gl.COLOR_ATTACHMENT0 + loc;
});
gl.drawBuffers(buffers);
Nicht vorhandene oder reservierte Namen
console.log(gl.getFragDataLocation(program, 'gibtEsNicht'));
console.log(gl.getFragDataLocation(program, 'gl_FragColor'));
// Robuste Hilfsfunktion
const requireFragLocation = (prog, name) => {
const loc = gl.getFragDataLocation(prog, name);
if (loc === -1) throw new Error(`Fragment-Ausgabe "${name}" nicht gefunden`);
return loc;
};
// Wichtig · Fallstricke
- Die Methode gibt nur nach einem erfolgreichen
linkProgram()sinnvolle Werte zurück. Den Link-Status prüfst du vorher mitgetProgramParameter(program, gl.LINK_STATUS). Bei einem nicht gelinkten Programm erzeugt die Methode den FehlerINVALID_OPERATION. - Sie gibt es nur in WebGL 2 (
getContext('webgl2')) und mit Shadern in GLSL ES 3.00 (#version 300 es). In WebGL 1 schreibst du stattdessen über die ErweiterungWEBGL_draw_buffersingl_FragData[n]. - In WebGL 2 gibt es kein
bindFragDataLocation(). Hat ein Shader mehrere Ausgaben, musst du bei jederlayout(location = N)angeben, sonst schlägt das Linken fehl. - Wird eine
out-Variable im Shader nicht benutzt, entfernt der Compiler sie unter Umständen. Dann kommt-1zurück. - Die Browser-Unterstützung ist gut: Chrome, Edge, Firefox und Safari 15+ unterstützen WebGL 2.